Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call stored proc from after insert trigger

Perhaps a stupid question!

If I call a stored proc from an After Insert trigger (T-SQL) - then how do I get the values of the "just inserted" data? e.g.

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

       EXEC createAuditSproc 'I NEED VALUES HERE!' 

I don't have any identity columns to worry about - I just want to use some of the "just inserted" values to pass into my sproc.

Edit: For clarification - I need this to call a sproc and not do a direct insert to the table, since the sproc does more than one thing. I'm working with some legacy tables I can't currently amend to do things 'properly' (time/resource/legacy code), so I have to work with what I have :(

like image 478
BlueChippy Avatar asked Feb 03 '11 15:02

BlueChippy


People also ask

Can you call a stored procedure from a trigger?

A: Yes, we can call stored procedure inside the trigger.

How do you call a stored procedure from a trigger in MySQL?

MySQL allows you to call a stored procedure from a trigger by using the CALL statement. By doing this, you can reuse the same stored procedure in several triggers. However, the trigger cannot call a stored procedure that has OUT or INOUT parameters or a stored procedure that uses dynamic SQL.


1 Answers

You get to the newly 'changed' data by using the INSERTED and DELETED pseudo-tables:

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

Given the example tables

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 : Apologies, I didn't address the bit about calling a Stored Proc. As per marc_s's comment, note that inserted / deleted can contain multiple rows, which complicates matters with a SPROC. Personally, I would leave the trigger inserting directly into the audit table without the encapsulation of a SPROC. However, if you have SQL 2008, you can use table valued parameters, like so:

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  

And then your trigger would be altered as like so:

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

you can then test that this works for both a single and multiple inserts

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

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

However, if you are using SQL 2005 or lower, you would probably need to use a cursor to loop through inserted passing rows to your SPROC, something too horrible to contemplate.

As a side note, if you have SQL 2008, you might look at Change Data Capture

Edit #2 : Since you need to call the proc, and if you are certain that you only insert one row ...

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;
like image 133
StuartLC Avatar answered Oct 01 '22 13:10

StuartLC