2011-02-03 19 views
14

Forse una domanda stupida!Chiama il proc memorizzato dopo il trigger di inserimento

Se richiamo un processo memorizzato da un trigger After Insert (T-SQL), come ottengo i valori dei dati "appena inseriti"? ad es.

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

     EXEC createAuditSproc 'I NEED VALUES HERE!' 

Non ho nessuna colonna di identità di cui preoccuparsi - voglio solo utilizzare alcuni dei valori "appena inseriti" a passare nel mio sproc.

Modifica: Per chiarimenti - ho bisogno di questo per chiamare uno sproc e non fare un inserimento diretto alla tabella, poiché lo sproc fa più di una cosa. Sto lavorando con alcune tabelle legacy che attualmente non posso modificare per fare cose 'correttamente' (tempo/risorsa/codice legacy), quindi devo lavorare con quello che ho :(

risposta

22

Si arriva al nuovo ' 'dati modificati utilizzando il INSERTED and DELETED pseudo-tabelle:

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 

dato l'esempio tabelle

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: Scuse, non mi rivolgo il bit di chiamare una stored procedure secondo. Il commento di marc_s, nota che inserito/de leted può contenere più righe, il che complica le cose con un SPROC. Personalmente, lascerei il trigger inserito direttamente nella tabella di controllo senza l'incapsulamento di un SPROC. Tuttavia, se si dispone di SQL 2008, è possibile utilizzare valori di tabella parametri, in questo modo:

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 

E poi il trigger sarebbe alterata come in questo modo:

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 

si può quindi verificare che questo funziona sia per una singola e multipla inserti

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

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

Tuttavia, se si utilizza SQL 2005 o inferiore, si sarebbe probabilmente bisogno di usare un cursore per scorrere in ciclo inserito passando righe al tuo SPROC, qualcosa di troppo Horr è possibile contemplare.

Come nota a margine, se si dispone di SQL 2008, si potrebbe guardare Change Data Capture

Modifica # 2: Dal momento che è necessario chiamare il proc, e se si è certi che si inserisce una sola riga. ..

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 e ricorda anche che le tabelle 'Inserito' e' Eliminato' possono contenere diverse righe, non solo una singola! Non assumere mai che una singola riga venga elaborata in un trigger! –

+0

Come ottengo quei valori come parametri proc memorizzati? Devo dichiararli tutti e quindi selezionare 'param1 = val1, @ param2 = val2' e quindi passare quelli in? – BlueChippy

+0

@ param1 = val1 è unidirezionale, ma dato che potresti lavorare con più righe, ti consiglio di implementare l'argomento della tabella o di usare un cursore per chiamare il proc memorizzato una volta per ogni riga di dati inserita. – Armand

Problemi correlati