2017-01-16 29 views
0

我想获得一个查询,可以帮助我实现类似下面的图像的东西:SQL服务器:从OUTPUT子句分裂一行到多行

Output result set

第一个表是结果一个SQL OUTPUT子句(插入和删除)。我想将这些结果分成一个新表格(如上图中的第二个表格)。所以我想有一行描述插入的记录,第二行描述删除的记录。

这是我的样本数据是如何产生的:

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 
+0

请发布[最小,Co完整和可验证的例子](http://stackoverflow.com/help/mcve)也检查[如何问](http://stackoverflow.com/help/how-to-ask)。 – wdosanjos

+0

为什么你首先有这样的表结构?在同一行上使用'Inserted_ID'和'Deleted_ID'似乎“奇怪”。这两者之间是否有任何实际/自然的关系? –

+0

嗨@srutzky。这只是一个例子。这不是我的数据库中的真正表格。另外,当使用带有UPDATE语句的OUTPUT子句时,SQL Server允许我们显示插入的记录和已删除的记录。 – Solution

回答

0
  1. 除非你使用的是MERGE语句,你不能同时INSERT并在同一DML操作DELETE。在inserteddeleted伪表中只有inserteddeleted伪表中的行的唯一时间是在UPDATE操作期间,在这种情况下,两者中的行将引用表中相同的实际行,在这些行的视图之前和之后。意思是,你不会看到Inserted_IDDeleted_ID不同的问题。

  2. 如果您使用的是MERGE,则应该已经具有所需格式的行,因为OUTPUT子句中的一行不会代表多行受到影响。含义:OUTPUT已经工作,你是想要它,而不是你说它确实。

0

尝试使用OUTER/CROSS APPLY操作:

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) 
0

尝试整理表格结构像(保持关注[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  
); 

然后将此解决您的问题:

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; 
+0

谢谢@Juozas,这是一个更详细的答案,它工作得很好。我无法标记为答案,因为我是quora新手,所以它不会允许我。但非常感谢! – Solution

+0

谢谢你提出一个有趣的问题! – Juozas