Вызов хранимой процедуры после триггера вставки - PullRequest
14 голосов
/ 03 февраля 2011

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

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

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

       EXEC createAuditSproc 'I NEED VALUES HERE!' 

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

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

1 Ответ

23 голосов
/ 03 февраля 2011

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

Редактировать : Извините, я не затронул вопрос о вызове хранимого процесса. В соответствии с комментарием 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, вы можете посмотреть Change Data Capture

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

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...