Вызов хранимой процедуры после триггера вставки

Возможно, глупый вопрос!

Если я вызываю хранимую процедуру из триггера After Insert (T-SQL), то как мне получить значения "только что вставленных" данных? например.

   CREATE TRIGGER dbo.MyTrigger
    ON  dbo.MyTable 
     AFTER INSERT
    AS 
     BEGIN

       EXEC createAuditSproc 'I NEED VALUES HERE!' 

У меня нет столбцов идентификаторов, о которых нужно беспокоиться - я просто хочу использовать некоторые из "только что вставленных" значений, чтобы перейти в мой sproc.

Изменить: для пояснения - мне нужно это, чтобы вызвать sproc и не делать прямую вставку в таблицу, так как sproc делает больше, чем одно. Я работаю с некоторыми устаревшими таблицами, которые я сейчас не могу изменить, чтобы делать что-то "правильно" (время/ресурс/устаревший код), поэтому мне нужно работать с тем, что у меня есть: (

Ответы

Ответ 1

Вы переходите к новым "измененным" данным, используя INSERTED и DELETED псевдо-таблицы:

CREATE TRIGGER dbo.MyTrigger     
    ON  dbo.MyTable       
    AFTER INSERT     
AS       
    BEGIN         
        INSERT INTO myTableAudit(ID, Name)
        SELECT i.ID, i.Name
           FROM inserted i;
    END

Учитывая примеры таблиц

create table myTable
(
    ID INT identity(1,1),
    Name varchar(10)
)
GO

create table myTableAudit
(
    ID INT,
    Name varchar(10),
    TimeChanged datetime default CURRENT_TIMESTAMP
)
GO

Изменить. Извиняюсь, я не обращал внимания на вызов Stored Proc. В соответствии с комментарием marc_s обратите внимание, что вставленный/удаленный может содержать несколько строк, что усложняет вопросы с помощью SPROC. Лично я оставил бы триггер, вставляемый непосредственно в таблицу аудита без инкапсуляции SPROC. Однако, если у вас есть SQL 2008, вы можете использовать параметры таблицы, например:

CREATE TYPE MyTableType AS TABLE
(
    ID INT,
    Name varchar(10)
);
GO

CREATE PROC dbo.MyAuditProc @MyTableTypeTVP MyTableType READONLY
AS
    BEGIN
        SET NOCOUNT ON;

        INSERT INTO myTableAudit(ID, Name)
        SELECT mtt.ID, mtt.Name
            FROM @MyTableTypeTVP mtt;
    END
GO  

И тогда ваш триггер будет изменен так:

ALTER TRIGGER dbo.MyTrigger
    ON  dbo.MyTable       
    AFTER INSERT     
AS       
    BEGIN         
        SET NOCOUNT ON;

        DECLARE @MyTableTypeTVP AS MyTableType;

        INSERT INTO @MyTableTypeTVP(ID, Name)
        SELECT i.ID, i.Name
            FROM inserted i;

        EXEC dbo.MyAuditProc @MyTableTypeTVP;
    END

вы можете проверить, что это работает как для одной, так и для нескольких вставок

insert into dbo.MyTable values ('single');

insert into dbo.MyTable 
    select 'double'
union
    select 'insert';

Однако, если вы используете SQL 2005 или ниже, вам, вероятно, нужно будет использовать курсор для циклического ввода вставленных строк прохода в ваш SPROC, что слишком ужасно, чтобы созерцать.

В качестве побочного примечания, если у вас есть SQL 2008, вы можете посмотреть Изменить сбор данных

Изменить # 2: так как вам нужно вызвать proc, и если вы уверены, что вы вставляете только одну строку...

ALTER TRIGGER dbo.MyTrigger
    ON  dbo.MyTable       
    AFTER INSERT     
AS       
    BEGIN         
        SET NOCOUNT ON;

        DECLARE @SomeInt INT;
        DECLARE @SomeName VARCHAR(10);

        SELECT TOP 1 @SomeInt = i.ID, @SomeName = i.Name
        FROM INSERTED i;

        EXEC dbo.MyAuditProc @SomeInt, @SomeName;
    END;