2017-01-16 28 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