执行存储过程时显示错误

时间:2016-10-18 10:14:09

标签: sql sql-server sql-server-2008 sql-server-2012

执行存储过程时出现问题。

错误如:

  

子查询返回的值超过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

3 个答案:

答案 0 :(得分: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中进行循环。使用基于集合的操作。

答案 1 :(得分: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)

您的上述查询会返回Incremental_Solr_Product.Id的多条记录,因此需要将其更改为

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)

所以它对你有用

答案 2 :(得分:1)

错误消息说明了一切。在SQL Server中,您不能在子查询中返回多个值。

问题在于:

 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。