Link to home
Start Free TrialLog in
Avatar of imstac73
imstac73

asked on

SQL Trigger with multiple insert statements not working

I have a trigger on one of my table that has multiple insert statements in it.  When the trigger kicks off it is only executing the first insert statement.  What do I need to do to get all of the insert statements to run.  Code attached.

ALTER TRIGGER [dbo].[UpdateForecastBreakdown]
   ON  [dbo].[Forecasts] 
   FOR Insert
AS 
Begin
INSERT INTO dbo.Forecasts_Breakdown(Forecast_KeyID, BreakdownType, lineorder, margin)
VALUES(@@IDENTITY, 'Labor', 1, 0)

INSERT INTO dbo.Forecasts_Breakdown(Forecast_KeyID, BreakdownType, lineorder, margin)
VALUES(@@IDENTITY, 'Subs/POs', 2, 0)


INSERT INTO dbo.Forecasts_Breakdown(Forecast_KeyID, BreakdownType, lineorder)
VALUES(@@IDENTITY, 'Materials', 3)

INSERT INTO dbo.Forecasts_Breakdown(Forecast_KeyID, BreakdownType, lineorder, margin)
VALUES(@@IDENTITY, 'Retainage', 4, 0)
end

Open in new window

Avatar of lcohan
lcohan
Flag of Canada image

You need to get a list of ALL the records identifier from INSERTED which is a internal SQL table and process them ALL one by one in a LOOP OR in a batch depending what you need to do.

So it would be something like:

DECLARE @rct int
SET @rct =      (select count(*) from INSERTED)

IF @rct = 1
BEGIN
      -- statements for single row to process here
END
ELSE IF @rct > 1
BEGIN

      DECLARE @id int
      DECLARE id_list CURSOR FOR (SELECT ID  FROM INSERTED)
      OPEN id_list
      FETCH next FROM id_list INTO @id
      WHILE @@fetch_status=0
            BEGIN

                  --statements to process one row from the batch
                  FETCH next FROM id_list INTO @id
            END

CLOSE id_list
DEALLOCATE id_list

END
Avatar of imstac73
imstac73

ASKER

So would I put all my insert statements in both locations where you have '-statements'?  

I"m not sure how the code above helps as there will only be one record added to the triggered table at a time.  

The problem I"m having is that I need to insert 4 records in my breakdown table for every one record that is added to the triggered 'Forecasts' table. And currently the trigger runs the first insert line and then dies.
ASKER CERTIFIED SOLUTION
Avatar of Scott Pletcher
Scott Pletcher
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think I figured it out.  From your code I figured out that I need to assign the @@identity to a variable as the trigger maybe couldn't find the identity id after the first insert statement.  I did this and tested it and it worked with me manually inserting a record into the triggered table. I'm going to watch it and see if the next record added automatically also works.
That's not the best method.

Please refresh this q and look at my suggested code.
lets understand this correctly...you said that "...trigger runs the first insert line and then dies. "
so my understanding was that you do a batch operation (insert or a batch delete/update where the result would be the same) in the table therefor the trigger dies because of that.
Is this what is happening? Whet is the error when the "trigger runs the first insert line and then dies. '?
I don't get an error..it just only adds the first insert record in my trigger code.  It is now working since I added the code to store the @@identity value in a variable and then call the variable within all the insert statements.
That is not an accurate method in any sense.  Good luck with that any time you insert more than one row at once, or a different trigger fires ahead of the current trigger, or any of a dozen other things.
This trigger fires in response to another trigger. What is the correct method to do it then?
Scott,
I am looking at your code posted: by: ScottPletcherPosted on 2013-01-23 at 11:27:41ID: 38810996 and I don't understand how this inserts 4 separate records.  To me it only looks like it inserts one record.

My process is as follows:
User enters record into Projects table
Trigger on Projects table inserts one record into Forecasts table
Trigger on Forecasts table  inserts four records into Forecasts_Breakdown table.
The CROSS JOIN generates the extra rows.

For example, run this SQL and you'll see that every input row gets joined to all 4 rows from the CROSS JOINed table:


SELECT
    ident, BreakdownType, lineorder
FROM (
    SELECT 1 AS ident UNION ALL
    SELECT 2
) AS inserted --simulate two "inserted" col values
CROSS JOIN (
    SELECT 'Labor' AS BreakdownType, 1 AS lineorder UNION ALL
    SELECT 'Subs/POs', 2 UNION ALL
    SELECT 'Materials', 3 UNION ALL
    SELECT 'Retainage', 4
) AS hardcoded_data
Just to clarify, a CROSS JOIN joins every row in the first table to every row in the second table.

So, if the first table had 10 rows, and the second table had 8 rows, a CROSS JOIN would produce 80 rows.