Sql server output 功能介紹
-
基本概念
【1.0】output的優劣
優勢:可以在進行DML 增刪改時輸出/查看/保存操作前后的數據
劣勢:如果要輸出,在數據量大的情況下,會占用內存資源,影響一點性能
OUTPUT 子句對於在 INSERT操作之后檢索標識列或計算列的值可能非常有用。
另外OUTPUT子句也可以在UPDATE和DELETE語句中使用,從插入表或刪除表中得到數值,並返回這些數值。
以下語句中不支持 OUTPUT 子句:
l 引用本地分區視圖、分布式分區視圖或遠程表的 DML 語句。
l 包含 EXECUTE 語句的 INSERT 語句。
l 不能將 OUTPUT INTO 子句插入視圖或行集函數。
簡潔的OUTPUT子句,使得向SQL Server導入數據的操作得到了極大的簡化。
【1.1】環境/版本要求
sql server 2005 版本及以上(無需打SP),即數字版本9.0.1399及以上
【1.2】Output在CRUD的區別
(1)對於INSERT,可以引用inserted表以查詢新行的屬性
基本形式:
insert into tableName output inserted.column values(value1,value2.......)
以用Inserted.* 表示所有列
(2)對於DELETE,可以引用deleted表以查詢舊行的屬性.在delete table output where
基本形式:
delete test101 output deleted.* where condition
也可以 deleted.column1,deleted.column2 這種形式輸出你想要的列明
(3)對於UPDATE,使用deleted表查詢被更新行在更改前的屬性,用inserted表標識被更新行在更改后的值. update table set c1= 1 output where
總結:
Deleted表存放由於執行Delete或Update語句而要從表中刪除的所有行。
Inserted表存放由於執行Insert或Update語句而要向表中插入的所有行。
| 對表的操作 |
Inserted邏輯表 |
Deleted邏輯表 |
| 增加記錄(insert) |
存放增加的記錄 |
無 |
| 刪除記錄(delete) |
無 |
存放被刪除的記錄 |
| 修改記錄(update) |
存放更新后的記錄 |
存放更新前的記錄 |
【1.3】輸出方式
1.可以輸出給調用方(客戶端應用程序)
直接 output insered.* 或 deleted.* 或 inserted.column1,deleted.column2
2.輸出給表
前提,被into的表已經存在
Inserted.* into tablename / deleted.* into tablename /
3.兩者皆可.
使用多個 output即可
Output inserted.* into new_tablename output inserted
【2】output實例演示
【2.1】insert
(0)創建測試表
-- drop table test103;
create table test103( num1 int,num2 int);
(1)基本形式案例
insert into test103 output inserted.* values(100,100),(200,200)
(2)輸出到客戶端
insert into test103 output inserted.* values(100,100),(200,200)

這里就輸出新插入的值到客戶端了。
(3)輸出到表
注意into后面的表(這里測試新建的保存表是test1033)必須已經存在且表結構與原表test3一致,否則表不存在會報錯:會報找不到對象語法錯誤。表結構不一致會標錯:列不匹配。
--構造保存表 test1033
Select * into test1033 from test103 where 1=2
--插入數據,並把改SQL操作新插入的數據存入一份到 test1033表中去
insert into test103 output inserted.* into test1033 values(100,100),(200,200)
測試:
(1)原表當前數據

(2)做insert output ,把該語句插入的數據保存一份到 test1033

結果對比:
(1)原表test103現在數據 (2)新存入表 test1033 數據

如圖可見,(2)中的操作把新插入的兩行數據即插入到原表test103,也保存到了test1033
(4)表和客戶端都輸出

如圖可見,在insert 中使用output 不影響insert本來的情況,只是會額外輸出新行的數據。
【2.2】delete
(0)創建測試表
這里我們直接使用上面的環境test103表;現有數據如下:

(1)基本形式
delete test103 output deleted.* where ……
(2)輸出到客戶端
delete test103 output deleted.* where num1>850

如上圖,我們原表num1>850的只有2跳數據,刪除了這兩條語句並輸出到了客戶端。
(3)輸出到表
【用 deleted.column1,deleted.column2…方式】
也可以用 delete test103 output deleted.* into test1033 where num1>700


如圖,delete 中使用output可以把刪除部分的數據輸出出來。需要保存到表test1033;
注意into后面的表(這里測試新建的保存表是test1033)必須已經存在且表結構與原表test3一致,否則表不存在會報錯:會報找不到對象語法錯誤。表結構不一致會標錯:列不匹配
這里使用了列出列名的方式來插入。之前insert 沒有演示這種方式。
(4)表和客戶端都輸出
與 [2.1]insert中的(4) 方式一樣,寫多個 output 即可,這里不再贅述
【2.3】update
(0)創建測試表
這里以test103為測試表,信息如下:

(1)基本形式
update test103 set id =1 output deleted.*,inserted.* where ………
--deleted為修改前,inserted為修改后
(2)輸出到客戶端
update test103 set num1='33' output deleted.*,inserted.* where num1=99

可以輸出修改前和修改后的值。
(3)輸出到表
注意into后面的表(這里測試新建的保存表是test1033)必須已經存在且表結構與原表test3一致,否則表不存在會報錯:會報找不到對象語法錯誤。表結構不一致會標錯:列不匹配

同時原表也完成了update語句功能

(4)表和客戶端都輸出
與 [2.1]insert中的(4) 方式一樣,寫多個 output 即可,這里不再贅述
【3】有自增鍵的表
【3.1】測試數據
create table test104(id int identity(1,1),num1 int,num2 int);
insert into test104 values(111,11),(222,22),(333,33);
【3.2】構造相同結構表
select * into test1044 from test104 where 1=2
【3.3】對有自增列表使用ouput 的兩種辦法
直接使用會報錯
(1)使用 set identity_insert test1044 on
該操作,使得當前會話可以對該表的自增列進行手動插入。
演示:
set identity_insert test1044 on
delete test104 output deleted.* into test1044 where id=1
set identity_insert test1044 off
這樣也不行,因為使用identity_insert 方式,必須要顯示使用列名,不能使用 *
正確方式:把列名一一列出來再 Into 進去才行
set identity_insert test1044 on ;
delete test104 output deleted.id,deleted.num1,deleted.num2 into test1044(id,num1,num2) where id=1;
set identity_insert test1044 off;
select * from test1044;
(2)去掉自增列即可
alter table 表名 add 字段名 int
update 表名 set 字段名=自增字段名
alter table 表名 drop column 自增字段名
exec sp_rename '字段名', '自增字段名', 'column'
如果表中沒數據,也可以直接刪除該列,再建一個與該列一樣的
【4】可以只插入一個值到表嗎?可以
但,沒有插入的值會是默認值
同理,也可以利用多個 output 來把不同值輸出保存到不同表
