SQL SERVER 2005中全新的OUTPUT子句添加數據記錄詳解(實戰篇)

實戰篇

A. 將 OUTPUT INTO 用於簡單 INSERT 語句

以下示例將行插入 ScrapReason 表,並使用 OUTPUT 子句將語句的結果返回到 @MyTableVar table 變量。由於 ScrapReasonID 列使用 IDENTITY 屬性定義,因此未在 INSERT 語句中爲該列指定一個值。但請注意,將在列 INSERTED.ScrapReasonID 內的 OUTPUT 子句中返回由數據庫引擎 爲該列生成的值。

 複製代碼
USE AdventureWorks;
GO
DECLARE @MyTableVar table( ScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT ScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

B. 將 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

C. 將 OUTPUT 用於 DELETE 語句

以下示例將刪除 ShoppingCartItem 表中的所有行。子句 OUTPUT DELETED.* 指定 DELETE 語句的結果(即已刪除的行中的所有列)返回到執行調用的應用程序。後面的 SELECT 語句驗證對 ShoppingCartItem 表所執行的刪除操作的結果。

 複製代碼
USE AdventureWorks;
GO
DELETE Sales.ShoppingCartItem
    OUTPUT DELETED.* ;

--Verify all rows in the table have been deleted.
SELECT COUNT(*) AS [Rows in Table] FROM Sales.ShoppingCartItem;
GO

D. 將 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;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
--Note that ModifiedDate reflects the value generated by an
--AFTER UPDATE trigger.
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

E. 使用 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;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, 
    VacationHoursDifference, ModifiedDate
FROM @MyTableVar;
GO
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

F. 在 UPDATE 語句中使用包含 from_table_name 的 OUTPUT INTO

以下示例使用指定的 ProductIDScrapReasonID,針對 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

G. 在 DELETE 語句中使用包含 from_table_name 的 OUTPUT INTO

以下示例將按照在 DELETE 語句的 FROM 子句中所定義的搜索條件刪除 ProductProductPhoto 表中的行。OUTPUT 子句返回所刪除表(DELETED.ProductIDDELETED.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;

--Display the results of the table variable.
SELECT ProductID, ProductName, ProductModelID, PhotoID 
FROM @MyTableVar
ORDER BY ProductModelID;
GO

H. 將 OUTPUT INTO 用於大型對象數據類型

以下示例使用 .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

I. 在 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

這是在 2004 年 4 月 12 日 ('2004-04-12') 生成的結果集。請注意,ScrapReasonIDActualModifiedDate 列反映由觸發器操作生成的值而不是 INSERT 語句中提供的值。

 複製代碼
ScrapReasonID  Name                  ModifiedDate
-------------  ---------------- -----------------------
17             My scrap reason       2004-04-12 16:23:33.050

J. 將 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

在單個語句中使用 OUTPUT 與 OUTPUT INTO

以下示例將按照在 DELETE 語句的 FROM 子句中所定義的搜索條件刪除 ProductProductPhoto 表中的行。OUTPUT INTO 子句將所刪除表(DELETED.ProductIDDELETED.ProductPhotoID)中的列以及 Product 表中的列返回到 @MyTableVar table 變量。在 FROM 子句中使用 Product 表來指定要刪除的行。OUTPUT 子句將 ProductProductPhoto 表中的 DELETED.ProductIDDELETED.ProductPhotoID 列以及行的刪除日期和時間返回到執行調用的應用程序。

 複製代碼
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
OUTPUT DELETED.ProductID, DELETED.ProductPhotoID, GETDATE() AS DeletedDate 
FROM Production.ProductProductPhoto AS ph
JOIN Production.Product as p 
    ON ph.ProductID = p.ProductID 
WHERE p.ProductID BETWEEN 800 and 810;

--Display the results of the table variable.
SELECT ProductID, ProductName, PhotoID, ProductModelID 
FROM @MyTableVar;
GO
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章