SQL - 子查询返回的值超过1

时间:2015-03-24 21:24:39

标签: sql sql-server

BEGIN TRANSACTION

DELETE FROM MessagesRead 
WHERE [To] <> 'Feadmin'
  AND [To] <> 'Catalonia'
  AND [To] <> 'Bromordia'
  AND [From] <> 'Feadmin'
  AND [From] <> 'Catalonia'
  AND [From] <> 'Bromordia'
  AND MessageID IN (SELECT MessageID 
                    FROM Messages 
                    WHERE TickNr < ((SELECT TickNumber FROM CurrentTick)-1000))
  AND Saved = 0 AND [Read] =1;

DELETE FROM Messages 
WHERE MessageID NOT IN (SELECT DISTINCT MessageID FROM MessagesRead);

DELETE FROM MessagesAdmin 
WHERE MessageID NOT IN (SELECT DISTINCT MessageID FROM Messages);

DELETE from DiscussionMessages 
WHERE DATEDIFF(DAY,Inserted,CURRENT_TIMESTAMP) > 6000

COMMIT TRANSACTION

我刚刚从SQL Server 2012升级到2014.我正在运行上述存储过程,该过程一直有效,直到收到错误消息:

  

Msg 512,Level 16,State 1,Procedure Engine_DeleteMessages,Line 9
  子查询返回的值超过1。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。

我显然已经解决了它不应该说WHERE TickNr <但是我想不出更好的方式来说明这个,或者为什么它在我升级之前一直有效?

3 个答案:

答案 0 :(得分:3)

这是一个非常好的错误消息,很有说服力。因此,您需要子查询通过使用where子句或TOP来返回单个值/行。

要么:

SELECT TickNumber FROM CurrentTick WHERE id = <someID>;

OR:

SELECT TOP 1 TickNumber FROM CurrentTick [ORDER BY some_col]

答案 1 :(得分:0)

你在CurrentTick中有多行吗?如果该表中只有一行,那么上面的查询就可以了。可能是该表中现在有2行或更多行吗?

答案 2 :(得分:0)

如果您想确保TickNr低于TickNumber中任何可能的CurrentTickALL运算符可能是个好例子:

AND MessageID IN (SELECT MessageID 
                    FROM Messages 
                    WHERE TickNr < ALL((SELECT TickNumber FROM CurrentTick)-1000))

这将针对子查询中返回的所有值测试TickNr

如果可以/应该只返回一行,则可以在子查询中使用top 1以确保子查询返回单个值。