2011-11-08 18 views
2

このトピックはすべてここにありますが、私はINSERT,UPDATE,ではありません。私の声明は平易でシンプルなSELECTの声明です。これまでのところ、私は1つになるまでデータベース内の116の異なる項目を扱ってきました。サブクエリが1つ以上の値を返しました

私は検索エンジンを持っており、私たちのデータベースにあるすべての単一の製品を情報に追加しています。これはすべてWebサイトで行われますが、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つの製品。 これは私が使用している声明です。なぜ誰が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 

Webサービスを呼び出すaspxページ:

<%@ 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> 

UPDATE:2011年11月9日 - 私はこの問題を持っているカップルより多くのレコードを発見しました。これらはProductID 331-335です。私はここで何が起こっているのか分かりません。これらの製品が実際には存在しないか、何らかのバグがある可能性がありますか? DISTINCTつの結果を意味するものではありません、私は、これはサブselectクエリであると仮定し

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

私は問題が何であるかを考え出しました。何らかの理由で、これらの問題のある製品は、データ項目に複数の値が割り当てられています(SHOULDは1つの項目しか持たない)。データベースが最近変更されたため、この5つの製品がすでに混乱していて、今すぐ見つかったと思います。

ありがとうございました!私はもっ​​と早くデータベースを調べることを考えていたと思います。 (約15のテーブルがあるので、私は最後にやるべきことだと思っています)

3

:ここ

はProductIDsと、このエラーを持って、それに対応するProductNamesの一覧です。 TOP 1を使用して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この危険なパターンに従うのを見ると、他人のコードを変更するのを恐れてはいけません。元々このコードを書いた人/ガールは、もはや同社とはあまり関係しておらず、今あなたは担当しています。あなたの人生も楽になります!とにかく、私はあなたがそれを整理して非常にうれしいです;) – Icarus

+0

ええ、あなたは正しいです。たとえそれが混乱であっても、それがあるように働くものを変えるのはちょっと神経質なことです。私は「現実の世界」に5ヶ月しかいませんでした。私は大学で十分に学ばなかったので、うまくいけば私は非常に長い間遅れていません! – jlg

関連する問題