2011-02-03 2 views
14

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

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

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

     EXEC createAuditSproc 'I NEED VALUES HERE!' 

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

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

ответ

22

Вы добираетесь до нового ' измененные»данные с помощью INSERTED and 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 

Edit: Извиняюсь, я не рассматривал немного о вызове хранимой Proc в пер. комментарий marc_s, обратите внимание, что insert/de убранный может содержать несколько строк, что усложняет вопросы с помощью 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

Edit # 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; 
+4

+1 а также помните, что таблицы 'Inserted' и' Deleted' потенциально содержат несколько строк - а не только один! Никогда не предполагайте, что только одна строка обрабатывается в триггере! –

+0

Как получить эти значения в качестве хранимых параметров процесса? Должен ли я объявить их все, а затем «select @ param1 = val1, @ param2 = val2», а затем передать их? – BlueChippy

+0

@ param1 = val1 - один из способов, но поскольку вы можете работать с несколькими строками, я рекомендую либо реализовать аргумент таблицы, либо использовать курсор для вызова сохраненного proc один раз для каждой строки вставленных данных. – Armand

Смежные вопросы