I am trying to get a query that can help me achieve something similar to the image below:
The first table is the result of a SQL OUTPUT
clause (both inserted and deleted). I would like to split these results into a new table (like the second one in the above image). So I want to have one row depicting the inserted records and the second row depicting the deleted records.
This is how my sample data was created:
select
inserted_ID = 1,
inserted_name = 'Brian',
inserted_phone = '123-456-7890',
operation_type1 = 'inserted',
deleted_id = 2,
deleted_name = 'James',
deleted_phone = '222-222-2222',
operation_type2 = 'Deleted'
into
#tbltest
Try to organize your table structure something like (keep attention on [uid]):
create table [my_table]
(
[id] int
,[name] nvarchar(256)
,[phone] nvarchar(256)
);
insert into [my_table]
values (1, 'Brian', '123-456-7890');
create table [my_log]
(
[inserted_id] int
,[inserted_name] nvarchar(256)
,[inserted_phone] nvarchar(256)
,[deleted_id] int
,[deleted_name] nvarchar(256)
,[deleted_phone] nvarchar(256)
,[uid] uniqueidentifier primary key
);
And then this solves your problem:
update [my_table]
set [id] = 2
,[name] = 'James'
,[phone] = '222-222-2222'
output
[deleted].[id]
,[deleted].[name]
,[deleted].[phone]
,[inserted].[id]
,[inserted].[name]
,[inserted].[phone]
,newid()
into [my_log]
(
[inserted_id]
,[inserted_name]
,[inserted_phone]
,[deleted_id]
,[deleted_name]
,[deleted_phone]
,[uid]
);
select
[id] = [id]
,[name] = [name]
,[phone] = [phone]
,[op_type] = CASE [op_type] WHEN 0 THEN 'Insert' ELSE 'Delete' END
from
(
select
[id] = [inserted_id]
,[name] = [inserted_name]
,[phone] = [inserted_phone]
,[op_type] = 0 -- insert
,[uid] = [uid]
from
[my_log]
union
select
[id] = [deleted_id]
,[name] = [deleted_name]
,[phone] = [deleted_phone]
,[op_type] = 1 -- delete
,[uid] = [uid]
from
[my_log]
) as [l]
order by
[l].[uid]
,[l].[op_type] ASC;
Unless you are using the MERGE
statement, you cannot both INSERT
and DELETE
in the same DML operation. The only time (outside of MERGE
) that you will have rows in both the inserted
and deleted
pseudo-tables is during an UPDATE
operation, and in that case, the rows in both will refer to the same actual rows in the tables, just the before and after views of those rows. Meaning, you won't see values like are what is being shown in the question where Inserted_ID
and Deleted_ID
differ.
If you are using MERGE
, then you should already have the rows in the desired format since one row from the OUTPUT
clause wouldn't represent multiple rows being affected. Meaning: OUTPUT
already works are you are wanting it to, not as you are stating that it does.
Try to use OUTER / CROSS APPLY operator:
select ...
from #Output / @Output as o
cross apply (
select o.insertedColA, o.insertedColB, 'I'
-- where o.insertedID is not null
union all
select o.deletedColB, ..., 'D'
-- where o.deletedID is not null
) as x(ColA, ColB, RowType)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.