2016-10-18 7 views
1

ストアドプロシージャの実行中に問題が発生しています。以下のようなストアドプロシージャの実行時にエラーが表示される

エラー:

サブクエリは複数の値を返しました。 =、!=、<、< =、>、> =、またはサブクエリが式として使用されている場合は、これは許可されません。ここで

は私のクエリです:

Create procedure [dbo].[Mysp] 
as 
BEGIN 
    Declare @Id int 
    Declare @MyspRemainingIdFromProduct varchar(max) 
    Declare @StoreDeleteQuery varchar(max) 
    Declare @i int 
    Declare @MyspAddIdFromProduct varchar(max) 

    set @MyspRemainingIdFromProduct = 
      (SELECT Mysp_abc_Product.Id 
      FROM Mysp_abc_Product 
      LEFT OUTER JOIN Product ON Mysp_abc_Product.ID = Product.ID 
      WHERE Product.ID IS NULL) 

    set @StoreDeleteQuery = 'DELETE FROM Mysp_abc_Product WHERE Id IN (' + @MyspRemainingIdFromProduct + ')' 

    exec(@StoreDeleteQuery) 

    set @MyspAddIdFromProduct = 
      (SELECT Product.Id 
      FROM Product 
      LEFT OUTER JOIN Mysp_abc_Product ON Mysp_abc_Product.ID = Product.ID 
      WHERE Mysp_abc_Product.ID IS NULL) 

    WHILE (@i <= @MyspAddIdFromProduct) 
    BEGIN 
     --Insert data into Mysp_abc_Product where condition is p.Deleted = 'False' or p.Published = 'True' or VisibleIndividually = 'True' 
     INSERT INTO Mysp_abc_Product(ProductId, abcStatus, IsDeleted, InTime, StoreId, LanguageId) 
      SELECT 
       p.Id, 1, 0, GETDATE(), s.Id, l.Id 
      FROM 
       Language l, Store s, Product p 
      LEFT JOIN 
       Mysp_abc_Product isp on isp.ProductId = p.Id 
      WHERE 
       isp.Id IS NULL 
       AND p.Deleted = 'False' 
       OR p.Published = 'True' OR VisibleIndividually = 'True' 

     --Insert data into Mysp_abc_Product where condition is p.Deleted = 'True' or p.Published = 'False' or VisibleIndividually = 'False' 
     INSERT INTO Mysp_abc_Product(ProductId, abcStatus, IsDeleted, InTime, StoreId, LanguageId) 
      SELECT 
       p.Id, 1, 1, GETDATE(), s.Id, l.Id 
      FROM 
       Language l, Store s, Product p 
      LEFT JOIN 
       Mysp_abc_Product isp ON isp.ProductId = p.Id 
      WHERE 
       isp.Id IS NULL 
       AND p.Deleted = 'True' 
       OR p.Published = 'False' 
       OR VisibleIndividually = 'False' 
    END 
END 
+1

エラーメッセージにすべてが表示されます。許可されていない行が1行以上返されるサブクエリがあります。 (おそらくその割り当て。) – jarlh

+2

[古いスタイルのJOINを使用して蹴る悪い習慣](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using- old-style-joins.aspx) - 古い形式の*カンマで区切られたテーブル*のリストが、ANSI - ** 92 ** SQL標準(*以上の* ANSI 'JOIN'構文)に置き換えられました。 20歳**前)、その使用はお勧めしません。そして、あなたは***間違いなく*** ***ミックス***二つのスタイル! –

+0

私は動的SQLの必要性を見ません。あなたが本当に他の選択肢を持っていない場合のみ、動的SQLを使用してください。 –

答えて

1
set @IncrementalRemainingIdFromProduct = 
     (SELECT Incremental_Solr_Product.Id 
     FROM Incremental_Solr_Product 
     LEFT OUTER JOIN Product ON Incremental_Solr_Product.ID = Product.ID 
     WHERE Product.ID IS NULL) 

set @IncrementalAddIdFromProduct = 
     (SELECT Product.Id 
     FROM Product 
     LEFT OUTER JOIN Incremental_Solr_Product ON Incremental_Solr_Product.ID = Product.ID 
     WHERE Incremental_Solr_Product.ID IS NULL) 

あなたの上記のクエリはそうだから、あなた

のために動作します

set @IncrementalRemainingIdFromProduct = 
     (SELECT TOP(1) Incremental_Solr_Product.Id 
     FROM Incremental_Solr_Product 
     LEFT OUTER JOIN Product ON Incremental_Solr_Product.ID = Product.ID 
     WHERE Product.ID IS NULL) 

にそれを変更する必要がIncremental_Solr_Product.Idために複数のレコードを返します。

+3

'TOP(n)' *を明示的な 'ORDER BY'節なしで使用すると無駄になります - " top(1) "を取得していますか?あなたは*発注*を定義していないので、基本的に**任意の行**を取得しています..... –

+0

しかし、複数のIDが必要な場合は、top(1)の代わりに何ができますか? – karan

+0

そして、もし私がトップ(n)をしていたら、 "無効なカラム名 'n'"というエラーを表示します。 – karan

1

エラーメッセージにすべてが記載されています。 SQLサーバーでは、サブクエリで複数の値を返すことはできません。

問題がである:

set @MyspRemainingIdFromProduct = 
      (SELECT Mysp_abc_Product.Id 
      FROM Mysp_abc_Product 
      LEFT OUTER JOIN Product ON Mysp_abc_Product.ID = Product.ID 
      WHERE Product.ID IS NULL) 

サブクエリが適切ではない、複数のIDを返します。

2

あなたはどこにでも問題があります。エラーはかなり明確です。それはあなたのコードではありません。

たとえば、deleteの呼び出しは方法が過ぎています。なぜ変数と動的SQLを使うのですか?ただ、実行します。

DELETE FROM Mysp_abc_Product 
    WHERE Id IN (SELECT Mysp_abc_Product.Id 
       FROM Mysp_abc_Product LEFT OUTER JOIN 
         Product 
         ON Mysp_abc_Product.ID = Product.ID 
       WHERE Product.ID IS NULL 
       ); 

あるいは、さらに多くのポイントにする:

DELETE FROM Mysp_abc_Product abc 
    WHERE NOT EXISTS (SELECT 1 
         FROM Product p 
         WHERE abc.ID = p.ID 
        ); 

これは、より簡潔です。より良いパフォーマンスが必要です。

注:これはコード内の最初の問題のみを解決します。より多くの問題があります。

私の助言は、各サブクエリを一度にテストすることによってストアドプロシージャを構築することです。 T-SQLではループを行わないでください。 セットベースの操作を使用してください。

+0

しかし、複数のidを追加したい場合は、top(1)に書いてデータを挿入したいのですが....ここで私のクエリは – karan

+0

に設定されています@MyspAddIdFromProduct = (SELECT Product.Id FROM Product LEFT OUTER JOIN Mysp_abc_Product ON Mysp_abc_Product.ID = Product.ID WHERE Mysp_abc_Product.ID IS NULL) – karan

+0

@karan。 。 。私はあなたのコメントを理解していません。一致するすべてのIDが削除されます。 –

関連する問題