Получить таблицу OUTPUT из SQL INSERT с помощью .NET

Я пытаюсь получить таблицу OUTPUT с помощью команды INSERT в базе данных SQL Server (v14).

 DECLARE @i TABLE (TICKET_ID int, CREATED_DATE datetime);

 INSERT INTO dbo.TICKET (SITE_ID, TICKET_TITLE, USER_ID) 
 OUTPUT INSERTED.TICKET_ID, INSERTED.CREATED_DATE INTO @i 
 VALUES (@s, @t, @q);

 SELECT * FROM @i;

У меня есть 3 параметра, которые заполняются для сайта, заголовка билета и пользователя с помощью @s, @t и @u соответственно.

Я вызываю команду, используя объект SqlClient.SqlDataReader с функцией ExecuteReader на платформе 4.5.

Команда успешно вставляет запись в таблицу базы данных, но не возвращает таблицу @i с идентификатором билета (автоинкремент) и датой создания (по умолчанию = GETDATE), которую я должен представить пользователю после сохранения в база данных.

Я поигрался с удалением @i TABLE в команде, но получаю ошибку .NET:

Целевая таблица 'name' оператора DML не может иметь никаких включенных триггеров, если оператор содержит предложение OUTPUT без предложения INTO.

Я нашел несколько ссылок, по которым можно их исправить, но это не решило мою проблему.

https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/ms971497(v=msdn.10)?redirectedfrom=MSDN

Невозможно использовать UPDATE с предложением OUTPUT когда на столе есть триггер

Могу ли я оказать какую-либо помощь в том, чего я пытаюсь достичь?


person Samuel    schedule 08.01.2020    source источник
comment
Вы пробовали свой запрос в SSMS? Это работает ? Если работает, проверьте свой .NET код.   -  person Squirrel    schedule 08.01.2020


Ответы (2)


Это кажется болезненным, но другой вариант может заключаться в следующем:

 INSERT INTO dbo.TICKET (SITE_ID, TICKET_TITLE, USER_ID) 
 VALUES (@s, @t, @q);

 SELECT TICKET_ID, CREATED_DATE 
 FROM dbo.TICKET 
 WHERE SITE_ID = @s AND TICKET_TITLE = @t AND USER_ID = @q;
person Greg Low    schedule 08.01.2020
comment
Я удалил предложение OUTPUT и использовал ссылку на идентификатор @@ для выполнения SELECT, чтобы получить нужные мне данные таблицы. - person Samuel; 09.01.2020

Не знаю, зачем тебе стол. Я думаю, вам нужно просто выполнить это:

       INSERT INTO dbo.TICKET (SITE_ID, TICKET_TITLE, USER_ID) 
       OUTPUT inserted.TICKET_ID, inserted.CREATED_DATE
       VALUES (@s, @t, @q);

Я не вижу значения в таблице. Когда вы выполняете этот оператор, он возвращает результаты клиенту, как и оператор SELECT.

Надеюсь, это поможет.

person Greg Low    schedule 08.01.2020
comment
Если я удалю ссылки на временную таблицу @i, я получаю следующее сообщение: The target table 'dbo.TICKET' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause. - person Samuel; 08.01.2020
comment
Есть ли триггер на целевой таблице? Для чего это? Было бы здорово, если бы он вам не понадобился. Невозможность сделать это - долгосрочная ошибка (по крайней мере, на мой взгляд), и я не думаю, что ее исправят в ближайшее время. - person Greg Low; 08.01.2020
comment
Поэтому, если вы застряли с триггером, вам нужно вернуться к исходному запросу. Есть ли шанс, что он вернется в виде нескольких наборов результатов? Вы пробовали вызвать у читателя вызов NextResultSet ()? (Посмотрите, не является ли это дополнительным набором результатов) - person Greg Low; 08.01.2020
comment
Зачем вам нужно использовать OUTPUT? Не могли бы вы сделать что-нибудь вроде select ticket_id, created_date from ticket where ticket_id = @@identity? - person iakobski; 08.01.2020
comment
Похоже, что в этой таблице на INSERT есть триггер, о котором я не знал. Итак, я удалил из команды предложение OUTPUT, а затем выполнил SELECT, используя идентификатор @@. - person Samuel; 09.01.2020
comment
Также не используйте @@ IDENTITY. Вместо этого используйте SCOPE_IDENTITY (). SCOPE_IDENTITY () дает вам последнее значение идентификатора в вашей текущей области. @@ IDENTITY дает вам последнее значение идентификации в вашем соединении. Итак, если вы выполняете INSERT, который запускает другой INSERT (через триггер), вы получите второе значение IDENTITY, а не то, которое хотите. SCOPE_IDENTITY () позволяет избежать этой проблемы. - person Greg Low; 09.01.2020