Reputation: 59
I've created trigger for my database which handles some insertion but when I add multiple values in 1 SQL query it doesn't work:
ALTER TRIGGER [dbo].[ConferenceDayTrigger]
ON [dbo].[Conferences]
AFTER INSERT
AS
BEGIN
DECLARE @ID INT
DECLARE @dayC INT
DECLARE @counter INT
SET @counter = 1
SET @ID = (SELECT IDConference FROM Inserted)
SET @dayC = (SELECT DATEDIFF(DAY, start,finish) FROM Inserted)
WHILE @counter <= @dayC + 1
BEGIN
EXEC AddConferenceDay @Id, @counter
SET @counter = @counter +1
END
END
For single insertion it works ok. But what should I change/add to make it execute for each row of inserted values?
Upvotes: 5
Views: 16639
Reputation: 1269853
If you cannot change the stored procedure, then this might be one of the (very few) cases when a cursor comes to the rescue. Double loops, in fact:
ALTER TRIGGER [dbo].[ConferenceDayTrigger]
ON [dbo].[Conferences]
AFTER INSERT
AS
BEGIN
DECLARE @ID INT;
DECLARE @dayC INT;
DECLARE @counter INT
SET @counter = 1;
DECLARE yucky_Cursor CURSOR FOR
SELECT IDConference, DATEDIFF(DAY, start,finish) FROM Inserted;
OPEN yucky_Cursor; /*Open cursor for reading*/
FETCH NEXT FROM yucky_Cursor INTO @ID, @dayC;
WHILE @@FETCH_STATUS = 0
BEGIN
WHILE @counter <= @dayC + 1
BEGIN
EXEC AddConferenceDay @Id, @counter;
SET @counter = @counter + 1;
END;
FETCH NEXT FROM yucky_Cursor INTO @ID, @dayC;
END;
CLOSE yucky_Cursor;
DEALLOCATE yucky_Cursor;
END;
I suspect there is a way to refactor and get rid of the cursor and use set-based operations.
Upvotes: 6
Reputation: 1
add these lines to your trigger
AFTER INSERT AS BEGIN
AFTER INSERT
AS
BEGIN
Declare @Count int;
Set @Count=@@ROWCOUNT;
IF @Count=0
Return;
SET NOCOUNT ON;
-- Insert statements for trigger here
Upvotes: 0
Reputation: 93724
When you insert more than one record, you need to cursor/while
to call the AddConferenceDay
procedure for each record.
But I will suggest you to alter your procedure to accept table type as input parameter. So that more than one ID
and dayC
as input to AddConferenceDay
procedure. It is more efficient than your current approach.
something like this
create type udt_Conferences as table (ID int,dayC int)
Alter the procedure to use udt_Conferences as input parameter
Alter procedure AddConferenceDay (@input udt_Conferences readonly)
as
begin
/* use @input table type instead of @Id and @counter variables */
end
To call the procedure update the trigger with created udt
ALTER TRIGGER [dbo].[ConferenceDayTrigger]
ON [dbo].[Conferences]
AFTER INSERT
AS
BEGIN
Declare @input udt_Conferences
insert into @input (ID,dayC)
select IDConference,DATEDIFF(DAY, start,finish) from Inserted
END
Upvotes: 0