【问题标题】:Error "Subquery returned more than 1 value" when updating a table更新表时出现错误“子查询返回超过 1 个值”
【发布时间】:2019-10-28 11:28:00
【问题描述】:

我有一个存储过程,它使用有关使用 TVP 传递给过程的一些文档的数据填充临时表的一部分:

DECLARE @TempDocumentsKeys AS TABLE ( ... );

DocumentID  Keyword         ProtocolNumber   ProtocolDate            FolderIndex
----------- --------------- ---------------- ----------------------- -----------
NULL        ARCHIVIO        277543           2019-10-02 00:00:00.000 111563
NULL        CIAN            277543           2019-10-02 00:00:00.000 111563
NULL        RICHIESTA       277543           2019-10-02 00:00:00.000 111563
NULL        ABILITAZIONI    277543           2019-10-02 00:00:00.000 111563
NULL        ARCHIVIO        277543           2019-10-02 00:00:00.000 128421
NULL        CIAN            277543           2019-10-02 00:00:00.000 128421
NULL        RICHIESTA       277543           2019-10-02 00:00:00.000 128421
NULL        ABILITAZIONI    277543           2019-10-02 00:00:00.000 128421

现在,在同一个过程中,我必须使用已存储到另一个临时表中的新插入的 ID 来更新这个 DocumentID 字段:

DECLARE @InsertedDocuments AS TABLE ( ... );

Keyword      DocumentID  ProtocolNumber   ProtocolDate            FolderIndex
------------ ----------- ---------------- ----------------------- -----------
NULL         81          277543           2019-10-02 00:00:00.000 111563
NULL         82          277543           2019-10-02 00:00:00.000 128421

所以@TempDocumentsKeys 临时表应该是这样的:

DocumentID  Keyword         ProtocolNumber   ProtocolDate            FolderIndex
----------- --------------- ---------------- ----------------------- -----------
81          ARCHIVIO        277543           2019-10-02 00:00:00.000 111563
81          CIAN            277543           2019-10-02 00:00:00.000 111563
81          RICHIESTA       277543           2019-10-02 00:00:00.000 111563
81          ABILITAZIONI    277543           2019-10-02 00:00:00.000 111563
82          ARCHIVIO        277543           2019-10-02 00:00:00.000 128421
82          CIAN            277543           2019-10-02 00:00:00.000 128421
82          RICHIESTA       277543           2019-10-02 00:00:00.000 128421
82          ABILITAZIONI    277543           2019-10-02 00:00:00.000 128421

.我正在尝试一个简单的UPDATE 声明

UPDATE @TempDocumentsKeys
SET DocumentID = 
    (SELECT INS.DocumentID FROM @InsertedDocuments AS INS 
    INNER JOIN @TempDocumentsKeys AS TCD ON 
        INS.ProtocolNumber = TCD.ProtocolNumber
        AND INS.ProtocolDate = TCD.ProtocolDate
        AND INS.FolderIndex = TCD.FolderIndex)

但我收到了这个错误:

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

为什么会这样?我不明白,JOIN 中的 ON 子句应该给我一个结果,而不是一组结果...

谢谢,大卫。

【问题讨论】:

  • 什么 WHERE 子句?
  • 这里的错误非常明确,您拥有的子查询 ((SELECT INS.DocumentID...)) 返回超过 1 行。引用所述子查询的表达式使用=,并且当子查询返回多行时明确不允许该运算符。
  • @forpas 对不起,你是对的,我的意思是“开”。固定。

标签: sql-server tsql


【解决方案1】:

不要使用子查询。 SQL Server 支持加入更新语句:

UPDATE TCD 
SET DocumentID = INS.DocumentID 
FROM @InsertedDocuments AS INS 
INNER JOIN @TempDocumentsKeys AS TCD 
    ON  INS.ProtocolNumber = TCD.ProtocolNumber
    AND INS.ProtocolDate = TCD.ProtocolDate
    AND INS.FolderIndex = TCD.FolderIndex

顺便说一句,你所拥有的是一个表变量。这与临时表不完全相同(以一个或两个主题标签开头 - #tempTable##globalTempTable

【讨论】:

    【解决方案2】:

    我们可以在此处使用可更新的 CTE 作为一种选择:

    WITH cte AS (
        SELECT t1.DocumentID AS DocDest, t2.DocumentID AS DocSrc
        FROM @TempDocumentsKeys t1
        INNER JOIN @InsertedDocuments t2
            ON t1.ProtocolNumber = t2.ProtocolNumber AND
               t1.ProtocolDate = t2.ProtocolDate AND
               t1.FolderIndex = t2.FolderIndex
    )
    
    UPDATE cte
    SET DocDest = DocSrc;
    

    这种方法允许您使用与您的第二次更新尝试非常相似的语法,除了这个版本实际上应该在 SQL Server 上工作。

    【讨论】:

      猜你喜欢
      • 2015-08-13
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 2015-01-08
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多