I’m converting a ColdFusion Project from Oracle 11 to MS SQL 2008. I used SSMA to convert the DB including triggers, procedures and functions. Sequences were mapped to IDENTITY columns.
I planned on using INSERT-Statements like
INSERT INTO mytable (col1, col2)
OUTPUT INSERTED.my_id
values('val1', 'val2')
This throws an error since the table has a trigger defined, that AFTER INSERT writes some of the INSERTED data to another table to keep a history of the data.
Microsoft writes:
If the OUTPUT clause is specified without also specifying the INTO
keyword, the target of the DML operation cannot have any enabled
trigger defined on it for the given DML action. For example, if the
OUTPUT clause is defined in an UPDATE statement, the target table
cannot have any enabled UPDATE triggers.
http://msdn.microsoft.com/en-us/library/ms177564.aspx
I’m now wondering what is the best practice fo firstly retrieve the generated id and secondly to “backup” the INSERTED data in a second table.
Is this a good approach for the INSERT? It works because the INSERTED value is not simply returned but written INTO a temporary variable. It works in my tests as Microsoft describes without throwing an error regarding the trigger.
<cfquery>
DECLARE @tab table(id int);
INSERT INTO mytable (col1, col2)
OUTPUT INSERTED.my_id INTO @tab
values('val1', 'val2');
SELECT id FROM @tab;
</cfquery>
Should I use the OUTPUT clause at all? When I have to write multiple clauses in one cfquery-block, shouldn’t I better use SELECT SCOPE_DENTITY() ?
Thanks and best,
Bernhard
This seems to work – the row gets inserted, the instead of trigger returns the result, the after trigger doesn’t interfere, and the after trigger logs to the table as expected:
Now, if you write this in your
cfquery, you should get a row back in output. I’m not CF-savvy so I’m not sure if it has to see some kind ofselectto know that it will be returning a result set (but you can try it in Management Studio to confirm I am not pulling your leg):Now you should just move your after insert logic to this trigger as well.
Be aware that right now you will get multiple rows back for (which is slightly different from the single result you would get from
SCOPE_IDENTITY()). This is a good thing, I just wanted to point it out.