Output子句日常灰常有用,而且用的地方也挺多,但是確好多時候被我們忽視,今天我就也簡單掃盲一下這個語句的用法。 Output子句 返回受 INSERT、UPDATE、DELETE 或 MERGE 語句影響的各行中的信息,或返回基於受這些語句影響的各行的表達式。 這些結果可以返回到處理應用程式,以
Output子句日常灰常有用,而且用的地方也挺多,但是確好多時候被我們忽視,今天我就也簡單掃盲一下這個語句的用法。
Output子句
返回受 INSERT、UPDATE、DELETE 或 MERGE 語句影響的各行中的信息,或返回基於受這些語句影響的各行的表達式。 這些結果可以返回到處理應用程式,以供在確認消息、存檔以及其他類似的應用程式要求中使用。 也可以將這些結果插入表或表變數。 另外,您可以捕獲嵌入的 INSERT、UPDATE、DELETE 或 MERGE 語句中 OUTPUT 子句的結果,然後將這些結果插入目標表或視圖(視圖並不能直接插入的,等下我說)。
下麵做下這4種類型的output 用法
先搞個測試表
CREATE TABLE [dbo].[AAA1] ( [ID] [int] PRIMARY KEY, [Col2] VARCHAR(100) ) ON [PRIMARY] GO CREATE TABLE [dbo].[AAA2] ( [ID] [int] PRIMARY KEY, [Col2] VARCHAR(100) ) ON [PRIMARY] GO
1、 insert
INSERT INTO dbo.AAA1 ( ID, Col2 ) OUTPUT Inserted.ID,Inserted.Col2 INTO AAA2(ID,Col2) VALUES ( 4,'1' )
這樣就可以在插入AAA1 的同時將插入的結果輸出插入到 AAA2 裡面。
我想到有2個常用的場景
1、有些功能想要寫入記錄的時候也同時插入一個記錄表來記錄操作,很多時候會想起觸發器。如果只是如此單純的操作,那麼真還不如使用一句output來得實惠了。但是這個也看具體場景,不扯太遠。
2、當我們單條插入的時候,要捕獲ID的話還可以使用 SCOPE_IDENTITY() 來獲取,但是如果批量的時候,要獲取插入的自增列對應的列,就可以使用OutPut 來捕獲了~
2、update
UPDATE AAA1 SET col2 = 'BB' OUTPUT Deleted.ID,Deleted.Col2,Inserted.ID,Inserted.Col2 WHERE ID = 1
在update 裡面呢,就會存在有 Deleted 和 inserted 2個臨時表,這個就類似於 觸發器裡面的 deleted表和 inserted 表了。可以捕捉到更新前後的值
3、deleted
DELETE FROM dbo.AAA1 OUTPUT Deleted.ID,Deleted.Col2 WHERE ID = 1
delete 也就是差不多,語法是一樣的。
4、 Merge
MERGE dbo.AAA1 AS TAR USING (SELECT 1,'a' ) AS SOUR(ID,Col2) ON 1 = 0 WHEN NOT MATCHED THEN INSERT (ID,Col2) VALUES (SOUR.ID,SOUR.Col2) OUTPUT $action,Deleted.*,Inserted.*;
Merge就有一個獨特一點的 $Action 的東東,這個的值會表示它的行動,有 'INSERT','UPDATE','DELETE' 3種動作。對於要捕捉在Merge裡面的變化就很好用啦~
Merge還有一點比較好用,可以把沒有插入到目標的列,也帶到Output裡面來~這個就可以清晰的看到每一行數據的對應情況了
但是Output雖好,但是還是會有一些限制,有些我遇到過,有些還沒測試過。(以下內容出自聯機文檔)
-
整個操作是原子的。 INSERT 語句和包含 OUTPUT 子句的嵌套 DML 語句要麼都執行,要麼整個語句都失敗。
-
以下限制適用於外層 INSERT 語句的目標:
-
目標不能為遠程表、視圖或公用表表達式。 (這個好理解,這個是指insert 的對象,並非指 output into 的對象)
-
目標不能有 FOREIGN KEY 約束,或者被 FOREIGN KEY 約束所引用。 (就是output into 的目標表不能帶外鍵)
-
不能對目標定義觸發器。
-
目標不能參與合併複製或事務複製的可更新訂閱。
-
-
對於嵌套的 DML 語句有以下限制:
-
目標不能為遠程表或分區視圖。
-
源本身不能包含 <dml_table_source> 子句。
-
-
在包含 <dml_table_source> 子句的 INSERT 語句中不支持 OUTPUT INTO 子句。
-
@@ROWCOUNT 返回僅由外層 INSERT 語句插入的行。
-
@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 僅返回由嵌套的 DML 語句生成的標識值,而不返回由外層 INSERT 語句生成的標識值。
-
查詢通知將語句作為單個實體進行處理,並且即使重大更改是來自外層 INSERT 語句本身,所創建的任何消息的類型也將是嵌套 DML 的類型。
-
在 <dml_table_source> 子句中,SELECT 和 WHERE 子句不能包括子查詢、聚合函數、排名函數、全文謂詞、執行數據訪問的用戶定義函數或是 TEXTPTR 函數。
其它東西~遇到了在繼續補充