Ошибка «Подзапрос возвратил более 1 значения» при обновлении таблицы - PullRequest
0 голосов
/ 28 октября 2019

У меня есть хранимая процедура, которая заполняет часть временной таблицы данными о некоторых документах, переданных в процедуру с использованием 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

Теперь, в рамках той же процедуры, мне придется обновитьэто поле 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 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения.

Почему это так? Я не понимаю, предложение ON в JOIN должно дать мне один единственный результат, а не набор результатов ...

Спасибо, Davide.

Ответы [ 2 ]

2 голосов
/ 28 октября 2019

Мы можем использовать обновляемый 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.

2 голосов
/ 28 октября 2019

Не используйте подзапрос. 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)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...