I have a T-SQL script that implements some synchronization logic using OUTPUT clause in MERGEs and INSERTs.
Now I
The OUTPUT clause allows for a selectable list. While this doesn't allow for multiple result sets, it does allow for one result set addressing all actions.
::=
{
[ OUTPUT INTO { @table_variable | output_table }
[ (column_list) ] ]
[ OUTPUT ]
}
I overlooked this myself until just the other day, when I needed to know the action taken for the row didn't want to have complicated logic downstream. The means you have a lot more freedom here. I did something similar to the following which allowed me to use the output in a simple means:
DECLARE @MergeResults TABLE (
MergeAction VARCHAR(50),
rowId INT NOT NULL,
col1 INT NULL,
col2 VARCHAR(255) NULL
)
MERGE INTO TARGET_TABLE AS t
USING SOURCE_TABLE AS s
ON t.col1 = s.col1
WHEN MATCHED
THEN
UPDATE
SET [col2] = s.[col2]
WHEN NOT MATCHED BY TARGET
THEN
INSERT (
[col1]
,[col2]
)
VALUES (
[col1]
,[col2]
)
WHEN NOT MATCHED BY SOURCE
THEN
DELETE
OUTPUT $action as MergeAction,
CASE $action
WHEN 'DELETE' THEN deleted.rowId
ELSE inserted.rowId END AS rowId,
CASE $action
WHEN 'DELETE' THEN deleted.col1
ELSE inserted.col1 END AS col1,
CASE $action
WHEN 'DELETE' THEN deleted.col2
ELSE inserted.col2 END AS col2
INTO @MergeResults;
You'll end up with a result set like:
| MergeAction | rowId | col1 | col2 |
| INSERT | 3 | 1 | new |
| UPDATE | 1 | 2 | foo |
| DELETE | 2 | 3 | bar |