Использование OUTPUT / INTO внутри вместо триггера вставки делает недействительной таблицу вставок - PullRequest
6 голосов
/ 20 марта 2010

У меня проблема с использованием таблицы вместо триггера вставки.

Таблица, которую я создал, содержит столбец идентификаторов. Мне нужно использовать вместо вставки триггер на этой таблице. Мне также нужно увидеть значение вновь вставленного идентификатора из моего триггера, который требует использования OUTPUT / INTO внутри триггера. Проблема в том, что клиенты, которые выполняют INSERT, не могут видеть вставленные значения.

Например, я создаю простую таблицу:

CREATE TABLE [MyTable](
 [MyID] [int] IDENTITY(1,1) NOT NULL,
 [MyBit] [bit] NOT NULL,
 CONSTRAINT [PK_MyTable_MyID] PRIMARY KEY NONCLUSTERED 
(
 [MyID] ASC
))

Далее я создаю простой вместо триггера:

create trigger [trMyTableInsert] on [MyTable] instead of insert
as
BEGIN
 DECLARE @InsertedRows table( MyID int,
                              MyBit bit);

 INSERT INTO [MyTable]
      ([MyBit])
   OUTPUT inserted.MyID,
          inserted.MyBit
   INTO @InsertedRows
   SELECT inserted.MyBit
     FROM inserted;

 -- LOGIC NOT SHOWN HERE THAT USES @InsertedRows
END;

Наконец, я пытаюсь выполнить вставку и получить вставленные значения:

DECLARE @tbl TABLE (myID INT) 

insert into MyTable 
 (MyBit)
OUTPUT inserted.MyID
  INTO @tbl
 VALUES (1)

 SELECT * from @tbl

Проблема в том, что все, что я когда-либо получу, это ноль. Я вижу, что строка была правильно вставлена ​​в таблицу. Я также знаю, что если я удалю OUTPUT / INTO из триггера, эта проблема исчезнет.

Есть мысли о том, что я делаю не так? Или как я хочу сделать что-то невыполнимое?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 13 ноября 2010

Вы не указали, какие у вас «клиенты», но если они являются .Net или подобным приложением, вам просто нужно удалить часть INTO вашего вывода. Ваши клиенты не могут видеть результаты, потому что они не возвращаются в наборе результатов.

Ваш триггер должен выглядеть так:

create trigger [trMyTableInsert] on [MyTable] instead of insert
as
BEGIN

 INSERT INTO [MyTable]
      ([MyBit])
   OUTPUT inserted.MyID,
          inserted.MyBit
   SELECT inserted.MyBit
     FROM inserted;

 -- LOGIC NOT SHOWN HERE THAT USES @InsertedRows
END;

Это приводит к тому, что вставки ведут себя как запрос выбора в том, что касается клиента - вы можете перебирать результаты, чтобы получить значение идентификатора (или другие специальные значения, такие как метка времени).

Так LinqToSql поддерживает идентифицирующие столбцы с триггерами вставки вместо вставок.

0 голосов
/ 12 сентября 2018

виновник здесь - фактически столбец идентичности; если вы замените его на последовательность, то все просто работает ™

create sequence testing_id as int start with 1 increment by 1

create table testing (id int default (next value for testing_id), s varchar(100))

create trigger tr_testing on testing instead of insert as
begin
    declare @inserted table (id int, s varchar(100))
    insert into testing
    output inserted.* into @inserted
    select * from inserted
end

declare @inserted table (id int, s varchar(100))
insert into testing (s)
output inserted.* into @inserted
values ('testing1'),('testing2')

select * from @inserted
...