Sql server 2005中output用法解析

一、关于output子句

 SQL Server 2005中的output子句,可以使你从修改语句(INSERT、UPDATE、DELETE)中将数据返回到表变量中。带结果的 DML 的有用方案包括清除和存档、消息处理应用程序以及其他方案。这一新的 OUTPUT 子句的语法为:

OUTPUT INTO @table_variable

 

可以通过引用插入的表和删除的表来访问被修改的行的旧/新映像,其方式与访问触发器类似。在 INSERT 语句中,只能访问插入的表。在 DELETE 语句中,只能访问删除的表。在 UPDATE 语句中,可以访问插入的表和删除的表。

二、实例说明

1、将 OUTPUT INTO 用于简单 INSERT 语句

以下示例将行插入 ScrapReason 表,并使用 OUTPUT 子句将语句的结果返回到 @MyTableVar table 变量。由于 ScrapReasonID 列使用 IDENTITY 属性定义,因此未在 INSERT 语句中为该列指定一个值。但请注意,将在列 INSERTED.ScrapReasonID 内的 OUTPUT 子句中返回由数据库引擎 为该列生成的值。

代码
 
   
use AdventureWorks
go
-- 定义一个表格变量
declare @mytablevar table ( ScrapReasonID smallint ,
Name1
varchar ( 50 ),
ModifiedDate
datetime )
insert into Production.ScrapReason
output inserted.ScrapReasonID,inserted.
[ Name ] ,inserted.ModifiedDate into @mytablevar
values ( ' operator error ' , getdate ());
-- 显示@mytablevar中的数据
select * from @mytablevar
-- 显示Production.ScrapReason表中的数据
select * from Production.ScrapReason
go

 

以上语句中inserted是一个临时表,当我们往数据表中插入一条数据的时候数据库会创建一个临时表inserted保存插入的记录;当我们删除某条记录的时候,数据库会创建一个临时表deleted保存删除的记录。以上语句把新插入的数据填充到表变量@mytablevar中,然后输出数据,可以看到@mytablevar中的记录和Production.ScrapReason中新插入的数据是一样的。

2、 将 OUTPUT 用于 INSERT…SELECT 语句

以下示例创建 EmployeeSales 表,然后通过使用 SELECT 语句检索源表中的数据将几行插入该表。同时,也计算了列 ProjectedSales 的值并将其插入该表中。OUTPUT 子句将 INSERT 语句的结果返回到执行调用的应用程序。最后的 SELECT 语句验证新 EmployeeSales 表的内容是否与 OUTPUT 子句的结果匹配。 

代码
 
   
use AdventureWorks
go
if object_id ( ' dbo.EmployeeSales ' , ' u ' ) is not null
drop table dbo.EmployeeSales
go
create table dbo.EmployeeSales
(
EmployeeID
nvarchar ( 11 ) not null ,
LastName
nvarchar ( 20 ) not null ,
FirstName
nvarchar ( 20 ) not null ,
CurrentSales
money not null ,
ProjectedSales
money not null

)
go
insert into dbo.EmployeeSales
output inserted.EmployeeID,inserted.LastName,inserted.FirstName,inserted.CurrentSales,inserted.ProjectedSales
SELECT e.EmployeeID, c.LastName, c.FirstName, sp.SalesYTD, sp.SalesYTD * 1.10
FROM HumanResources.Employee AS e
INNER JOIN Sales.SalesPerson AS sp
ON e.EmployeeID = sp.SalesPersonID
INNER JOIN Person.Contact AS c
ON e.ContactID = c.ContactID
WHERE e.EmployeeID LIKE ' 2% '
ORDER BY c.LastName, c.FirstName;
GO
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
FROM dbo.EmployeeSales;
GO

 

3、  将 OUTPUT 用于 DELETE 语句

以下示例将删除 ShoppingCartItem 表中的所有行。子句 OUTPUT DELETED.* 指定 DELETE 语句的结果(即已删除的行中的所有列)返回到执行调用的应用程序。后面的 SELECT 语句验证对 ShoppingCartItem 表所执行的删除操作的结果。 

 

 
  

USE AdventureWorks;
GO
DELETE Sales.ShoppingCartItem
OUTPUT DELETED.
* ;

-- 验证表中所有数据都被删除
SELECT COUNT ( * ) AS [ Rows in Table ] FROM Sales.ShoppingCartItem;
GO

4、 将 OUTPUT INTO 用于 UPDATE

下面的示例将 Employee 表中 VacationHours 列的前 10 行更新 25%。OUTPUT 子句将返回 VacationHours 值,该值在将列 DELETED.VacationHours 中的 UPDATE 语句和列 INSERTED.VacationHours 中的已更新值应用于 @MyTableVar table 变量之前存在。
在它后面的两个 SELECT 语句返回 @MyTableVar 中的值以及 Employee 表中更新操作的结果。请注意,INSERTED.ModifiedDate 列中的结果与 Employee 表中的 ModifiedDate 列不具有相同的值。这是因为对 Employee 表定义了将 ModifiedDate 的值更新为当前日期的 AFTER UPDATE 触发器。但是,从 OUTPUT 中返回的列反映触发器激发之前的数据。
 

代码
 
   
USE AdventureWorks;
GO
DECLARE @MyTableVar table (
EmpID
int NOT NULL ,
OldVacationHours
int ,
NewVacationHours
int ,
ModifiedDate
datetime );
UPDATE TOP ( 10 ) HumanResources.Employee
SET VacationHours = VacationHours * 1.25
OUTPUT INSERTED.EmployeeID,
DELETED.VacationHours,
INSERTED.VacationHours,
INSERTED.ModifiedDate
INTO @MyTableVar ;
-- 显示@MyTableVar的值
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar ;
GO
-- 显示插入表的值
SELECT TOP ( 10 ) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

5、 使用 OUTPUT INTO 返回表达式

以下示例在示例 D 的基础上生成,方法是通过将 OUTPUT 子句中的表达式定义为已更新的 VacationHours 值与应用更新之前的 VacationHours 值之间的差异。该表达式的值返回到列 VacationHoursDifference 中的 @MyTableVar table 变量。

代码
 
   
USE AdventureWorks;
GO
DECLARE @MyTableVar table (
EmpID
int NOT NULL ,
OldVacationHours
int ,
NewVacationHours
int ,
VacationHoursDifference
int ,
ModifiedDate
datetime );
UPDATE TOP ( 10 ) HumanResources.Employee
SET VacationHours = VacationHours * 1.25
OUTPUT INSERTED.EmployeeID,
DELETED.VacationHours,
INSERTED.VacationHours,
INSERTED.VacationHours
- DELETED.VacationHours,
INSERTED.ModifiedDate
INTO @MyTableVar ;
-- 显示表变量中的数据
SELECT EmpID, OldVacationHours, NewVacationHours,
VacationHoursDifference, ModifiedDate
FROM @MyTableVar ;
GO
SELECT TOP ( 10 ) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

  

6、 在 UPDATE 语句中使用包含 from_table_name 的 OUTPUT INTO

以下示例使用指定的 ProductID 和 ScrapReasonID,针对 WorkOrder 表中的所有工作顺序更新 ScrapReasonID 列。OUTPUT INTO 子句返回所更新表 (WorkOrder) 中的值以及 Product 表中的值。在 FROM 子句中使用 Product 表来指定要更新的行。由于 WorkOrder 表具有对其定义的 AFTER UPDATE 触发器,因此需要 INTO 关键字。 

代码
 
   
USE AdventureWorks;
GO
DECLARE @MyTestVar table (
OldScrapReasonID
int NOT NULL ,
NewScrapReasonID
int NOT NULL ,
WorkOrderID
int NOT NULL ,
ProductID
int NOT NULL ,
ProductName
nvarchar ( 50 ) NOT NULL );
UPDATE Production.WorkOrder
SET ScrapReasonID = 4
OUTPUT DELETED.ScrapReasonID,
INSERTED.ScrapReasonID,
INSERTED.WorkOrderID,
INSERTED.ProductID,
p.Name
INTO @MyTestVar
FROM Production.WorkOrder AS wo
INNER JOIN Production.Product AS p
ON wo.ProductID = p.ProductID
AND wo.ScrapReasonID = 16
AND p.ProductID = 733 ;

SELECT OldScrapReasonID, NewScrapReasonID, WorkOrderID,
ProductID, ProductName
FROM @MyTestVar ;
GO

7、在 DELETE 语句中使用包含 from_table_name 的 OUTPUT INTO

以下示例将按照在 DELETE 语句的 FROM 子句中所定义的搜索条件删除 ProductProductPhoto 表中的行。OUTPUT 子句返回所删除表(DELETED.ProductID、DELETED.ProductPhotoID)中的列以及 Product 表中的列。在 FROM 子句中使用该表来指定要删除的行。

 

代码
 
   
USE AdventureWorks
GO
DECLARE @MyTableVar table (
ProductID
int NOT NULL ,
ProductName
nvarchar ( 50 ) NOT NULL ,
ProductModelID
int NOT NULL ,
PhotoID
int NOT NULL );

DELETE Production.ProductProductPhoto
OUTPUT DELETED.ProductID,
p.Name,
p.ProductModelID,
DELETED.ProductPhotoID
INTO @MyTableVar
FROM Production.ProductProductPhoto AS ph
JOIN Production.Product as p
ON ph.ProductID = p.ProductID
WHERE p.ProductModelID BETWEEN 120 and 130 ;

SELECT ProductID, ProductName, ProductModelID, PhotoID
FROM @MyTableVar
ORDER BY ProductModelID;
GO

 

8、 将 OUTPUT INTO 用于大型对象数据类型s  

以下示例使用 .WRITE 子句更新 Production.Document 表内 DocumentSummary 这一 nvarchar(max) 列中的部分值。通过指定替换单词、现有数据中要替换的单词的开始位置(偏移量)以及要替换的字符数(长度),将单词 components 替换为单词 features。此示例使用 OUTPUT 子句将 DocumentSummary 列的前像和后像返回到 @MyTableVar table 变量。请注意,将返回 DocumentSummary 列的全部前像和后像。

代码
 
   
USE AdventureWorks;
GO
DECLARE @MyTableVar table (
DocumentID
int NOT NULL ,
SummaryBefore
nvarchar ( max ),
SummaryAfter
nvarchar ( max ));
UPDATE Production.Document
SET DocumentSummary .WRITE (N ' features ' , 28 , 10 )
OUTPUT INSERTED.DocumentID,
DELETED.DocumentSummary,
INSERTED.DocumentSummary
INTO @MyTableVar
WHERE DocumentID = 3 ;
SELECT DocumentID, SummaryBefore, SummaryAfter
FROM @MyTableVar ;
GO

9、 在 INSTEAD OF 触发器中使用 OUTPUT

以下示例在触发器中使用 OUTPUT 子句返回触发器操作的结果。首先,创建一个 ScrapReason 表的视图,然后对该视图定义 INSTEAD OF INSERT 触发器,从而使用户只修改基表的 Name 列。由于列 ScrapReasonID 是基表中的 IDENTITY 列,因此触发器将忽略用户提供的值。这允许数据库引擎 自动生成正确的值。同样,用户为 ModifiedDate 提供的值也被忽略并设置为正确的日期。OUTPUT 子句返回实际插入 ScrapReason 表中的值。 

代码
 
   
UUSE AdventureWorks;
GO
IF OBJECT_ID ( ' dbo.vw_ScrapReason ' , ' V ' ) IS NOT NULL
DROP VIEW dbo.vw_ScrapReason;
GO
CREATE VIEW dbo.vw_ScrapReason
AS ( SELECT ScrapReasonID, Name, ModifiedDate
FROM Production.ScrapReason);
GO
CREATE TRIGGER dbo.io_ScrapReason
ON dbo.vw_ScrapReason
INSTEAD
OF INSERT
AS
BEGIN
-- ScrapReasonID is not specified in the list of columns to be inserted
--
because it is an IDENTITY column.
INSERT INTO Production.ScrapReason (Name, ModifiedDate)
OUTPUT INSERTED.ScrapReasonID, INSERTED.Name,
INSERTED.ModifiedDate
SELECT Name, getdate ()
FROM inserted;
END
GO
INSERT vw_ScrapReason (ScrapReasonID, Name, ModifiedDate)
VALUES ( 99 , N ' My scrap reason ' , ' 20030404 ' );
GO

 

10、  将 OUTPUT INTO 用于标识列和计算列

下面的示例创建 EmployeeSales 表,然后使用 INSERT 语句向其中插入若干行,并使用 SELECT 语句从源表中检索数据。EmployeeSales 表包含标识列 (EmployeeID) 和计算列 (ProjectedSales)。由于这些值是在插入操作期间由数据库引擎生成的,因此,不能在 @MyTableVar 中定义上述两列。

代码
 
   
USE AdventureWorks ;
GO
IF OBJECT_ID ( ' dbo.EmployeeSales ' , ' U ' ) IS NOT NULL
DROP TABLE dbo.EmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( EmployeeID
int IDENTITY ( 1 , 5 ) NOT NULL ,
LastName
nvarchar ( 20 ) NOT NULL ,
FirstName
nvarchar ( 20 ) NOT NULL ,
CurrentSales
money NOT NULL ,
ProjectedSales
AS CurrentSales * 1.10
);
GO
DECLARE @MyTableVar table (
LastName
nvarchar ( 20 ) NOT NULL ,
FirstName
nvarchar ( 20 ) NOT NULL ,
CurrentSales
money NOT NULL
);

INSERT INTO dbo.EmployeeSales (LastName, FirstName, CurrentSales)
OUTPUT INSERTED.LastName,
INSERTED.FirstName,
INSERTED.CurrentSales
INTO @MyTableVar
SELECT c.LastName, c.FirstName, sp.SalesYTD
FROM HumanResources.Employee AS e
INNER JOIN Sales.SalesPerson AS sp
ON e.EmployeeID = sp.SalesPersonID
INNER JOIN Person.Contact AS c
ON e.ContactID = c.ContactID
WHERE e.EmployeeID LIKE ' 2% '
ORDER BY c.LastName, c.FirstName;

SELECT LastName, FirstName, CurrentSales
FROM @MyTableVar ;
GO
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
FROM dbo.EmployeeSales;
GO

 

 

 

 

 

 

转载于:https://www.cnblogs.com/yuananyun/archive/2010/12/04/1896276.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值