2011-11-08 123 views
2

我知道這個題目是所有的地方,但我沒有做一個INSERTUPDATEDELETE。我的陳述是一個簡單而簡單的SELECT聲明,迄今爲止我已經在我的數據庫中處理了116個不同的項目,直到我找到一個。子查詢返回多個值

我有一個搜索引擎,並打算通過每一個產品在我們的數據庫將信息添加到它。這一切都是通過網站完成的,但是當我搜索ProductID 331並點擊它時,它會轉到錯誤頁面,說Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

這對我來說沒有任何意義,只有這個網站會出錯一種產品。 這是我正在使用的聲明。有誰知道爲什麼1個產品會導致這個錯誤?

的WebService:

Public Class ProductSearch 
Inherits System.Web.Services.WebService 
<WebMethod()> _ 
Public Function GetProducts(ByVal prefixText As String, ByVal count As Integer) 
          As String() 
    Dim ProductSql As String = "Select DISTINCT ProductID, ProductName 
           FROM Product WHERE ProductName 
           LIKE '%' & @prefixText & '%' 
           ORDER BY ProductName ASC" 
    Using sqlConn As New SqlConnection 
    (System.Configuration.ConfigurationManager.ConnectionStrings 
    ("LocalSqlServer").ConnectionString) 
     sqlConn.Open() 
     Dim myCommand As New SqlCommand(ProductSql, sqlConn) 
     myCommand.Parameters.Add("@prefixText", SqlDbType.VarChar, 50) 
           .Value = prefixText 
     Dim myReader As SqlDataReader = myCommand.ExecuteReader() 
     Dim myTable As New DataTable 
     myTable.TableName = "ProductSearch" 
     myTable.Load(myReader) 
     sqlConn.Close() 
     Dim items As String() = New String(myTable.Rows.Count - 1) {} 
     Dim i As Integer = 0 
     For Each dr As DataRow In myTable.Rows 
      Dim id As String = dr("ProductID").ToString() 
      Dim name As String = dr("ProductName").ToString() 
      Dim item As String = AjaxControlToolkit.AutoCompleteExtender 
           .CreateAutoCompleteItem(name, id) 
      items.SetValue(item, i) 
      i += 1 
     Next 
     Return items 
    End Using 
End Function 
End Class 

aspx頁面調用web服務:

<%@ Page Title="Product Search" Language="VB" MasterPageFile="~/MasterPage.master" 
AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="Default" %> 

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" 
TagPrefix="asp" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> 
<script type="text/javascript"> 
function AutoCompleteClientMethod(source, eventArgs) { 
    var value = eventArgs.get_value(); 
    window.location = ("/Product/Default.aspx?id=" + value) 
} 
</script> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="body" Runat="Server"> 


    <asp:ScriptManager ID="ScriptManager1" runat="server"> 
    <Services> 
     <asp:ServiceReference Path="ProductSearch.asmx" /> 
    </Services> 
</asp:ScriptManager>  


    <asp:TextBox ID="Search" runat="server" AutoComplete="off"></asp:TextBox> 
    <asp:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server" 
     TargetControlID="Search" ServicePath="~/ProductSearch.asmx" 
     ServiceMethod="GetProducts" MinimumPrefixLength="1" CompletionSetCount="120" 
     EnableCaching="true" OnClientItemSelected="AutoCompleteClientMethod"> 
    </asp:AutoCompleteExtender> 
    </div><!--End of main div --> 
</asp:Content> 

更新:11/9/2011 - 我已經發現一對夫婦更多的記錄有這個問題。他們是產品ID 331-335。我不知道這裏發生了什麼。難道這些產品不是真的存在,或者它們有某種錯誤?

這裏是ProductIDs,並且有這樣的錯誤及其對應的ProductNames的列表:

122 'Managed account section of the Web Site' 
331 'Elliott Wave Principle Key to Market Behavior' 
332 'Targeting Profitable Entry & Exit Points' 
333 'Essentials of Trading It's not WHAT You Think, It's HOW You Think' 
334 'Exceptional Trading The Mind Game' 
335 'Fibonacci Analysis' 
+3

中有沒有子查詢,你一定是你的代碼中完整的查詢?次要的問題:PrefixText將是更好的也可以是綁定變量,而不是字符串連接,以避免潛在的SQL注入 – Andrew

+0

@Andrew我更新了我的代碼 – jlg

+0

我沒有這使我想知道爲什麼這個錯誤是發生任何的子查詢。我能想到的唯一的事情是,當javascript函數嘗試重定向用戶時,它的功能會拉回多個值。 – jlg

回答

0

我想通了什麼問題。出於某種原因,這些有問題的產品在應該只有一個項目的數據字段中爲它們分配了多個值。數據庫最近已經改變,所以不會發生,但我想這5個產品已經搞砸了,現在已經被發現了。

感謝所有的幫助傢伙!我希望我能早點考慮進一步檢查數據庫。 (大約有15桌,所以它通常是什麼,我想做到最後)

3

我想這是子選擇查詢,DISTINCT並不意味着一個結果。您可以使用TOP 1來保證一個結果,但不能保證它是您想要的結果。

Select TOP 1 DISTINCT ProductID, ProductName 
FROM Product WHERE ProductName 
LIKE '%" & prefixText & "%' 
ORDER BY ProductName ASC 
+0

我試過,但現在我的搜索引擎不起作用。 :(沒有結果顯示 – jlg

3

除了瑞克的答案,我會補充說,你不應該連接字符串來形成SQL語句。改用參數化查詢。字符串串聯暴露給你SQL注入攻擊。另外,通過使用參數化查詢,如果可以重用查詢計劃,您可能會獲得性能。

See this other StackOverflow post for a good discussion regarding parametrized queries on VB.NET.

+0

我不確定如何參數化前綴文本,但用戶在我的另一個帖子上回來的時候實際上已經有了整個時間的答案。我更新了它:) – jlg

+0

@jlg當你看到它遵循這種危險模式時,不要害怕改變別人的代碼。最初編寫代碼的人/ gal可能不再與該公司在一起,現在你負責了。它也會讓你的生活更輕鬆!無論如何,我很高興你整理出來;) – Icarus

+0

是的,你說得對。即使它是一團糟,改變現有方式的東西也是有點神經過於緊張。我只有5個月的「現實世界」。我在大學時沒有足夠的學習,所以希望我不會太落後! – jlg