INSERT 範例 (Transact-SQL)
本主題提供在 SQL Server 2008 R2 中使用 Transact-SQLINSERT 陳述式的範例。這些 INSERT 範例會依下列類別目錄分組。
類別目錄 |
代表性語法元素 |
---|---|
基本語法 |
INSERT • 資料表值建構函式 |
處理資料行值 |
IDENTITY • NEWID • 預設值 • 使用者定義型別 |
從其他資料表插入資料 |
INSERT…SELECT • INSERT…EXECUTE • WITH 通用資料表運算式 • TOP |
指定標準資料表以外的目標物件 |
檢視 • 資料表變數 |
將資料列插入遠端資料表 |
連結的伺服器 • OPENQUERY 資料列集函數 • OPENDATASOURCE 資料列集函數 |
大量匯入資料表或資料檔案中的資料 |
INSERT…SELECT • OPENROWSET 函數 |
使用提示來覆寫查詢最佳化工具的預設行為 |
資料表提示 |
擷取 INSERT 陳述式的結果 |
OUTPUT 子句 |
基本語法
本節的範例會使用所需的最少語法來示範 INSERT 陳述式的基本功能。
A. 插入單一資料列
下列範例會在 Production.UnitMeasure 資料表中插入一個資料列。此資料表中的資料行為 UnitMeasureCode、Name 和 ModifiedDate。由於提供了所有資料行的值,而且依照資料表中資料行的相同順序來列出它們,因此,不需要在資料行清單中指定資料行名稱。.
USE AdventureWorks2008R2;
GO
INSERT INTO Production.UnitMeasure
VALUES (N'FT', N'Feet', '20080414');
GO
B. 插入多個資料列
下列範例會透過單一 INSERT 陳述式,使用資料表值建構函式將三個資料列插入 Production.UnitMeasure 資料表中。由於提供了所有資料行的值,而且依照資料表中資料行的相同順序來列出它們,因此,不需要在資料行清單中指定資料行名稱。
USE AdventureWorks2008R2;
GO
INSERT INTO Production.UnitMeasure
VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923'), (N'Y3', N'Cubic Yards', '20080923');
GO
C. 插入與資料表資料行順序不同的資料
下列範例會利用資料行清單來明確指定插入每個資料行的值。Production.UnitMeasure 資料表中的資料行順序是 UnitMeasureCode、Name、ModifiedDate;不過,這些資料行不會依照 column_list. 中的順序來列出。
USE AdventureWorks2008R2;
GO
INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode,
ModifiedDate)
VALUES (N'Square Yards', N'Y2', GETDATE());
GO
處理資料行值
本節的範例會示範將值插入資料行的方法,該資料行是使用 IDENTITY 屬性或 DEFAULT 值所定義,或是使用類似 uniqueidentifer 或使用者定義型別資料行的資料類型所定義。
A. 將資料插入包含有預設值之資料行的資料表
下列範例示範如何將資料列插入資料表,該資料表包含的資料行會自動產生值或是具有預設值。Column_1 是一個計算資料行,它會將字串與插入 column_2 的值串連一起來自動產生某個值。Column_2 是以預設的條件約束定義。如果此資料行並未指定值,就會使用預設值。Column_3 會以 rowversion 資料類型定義,該資料類型會自動產生唯一的遞增二進位數字。Column_4 不會自動產生值。如果未指定這個資料行的值,就會插入 NULL。INSERT 陳述式會插入包含部分 (而非全部) 資料行值的資料列。在最後一個 INSERT 陳述式中,並未指定任何資料行,只會使用 DEFAULT VALUES 子句插入預設值。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1
(
column_1 AS 'Computed column ' + column_2,
column_2 varchar(30)
CONSTRAINT default_name DEFAULT ('my column default'),
column_3 rowversion,
column_4 varchar(40) NULL
);
GO
INSERT INTO dbo.T1 (column_4)
VALUES ('Explicit value');
INSERT INTO dbo.T1 (column_2, column_4)
VALUES ('Explicit value', 'Explicit value');
INSERT INTO dbo.T1 (column_2)
VALUES ('Explicit value');
INSERT INTO T1 DEFAULT VALUES;
GO
SELECT column_1, column_2, column_3, column_4
FROM dbo.T1;
GO
B. 將資料插入具有識別欄位的資料表
下列範例會顯示將資料插入識別欄位的不同方法。前兩個 INSERT 陳述式允許可用於產生新資料列的識別值。第三個 INSERT 陳述式利用 SET IDENTITY_INSERT 陳述式來覆寫資料行的 IDENTITY 屬性,且會將明確的值插入識別欄位中。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1 ( column_1 int IDENTITY, column_2 VARCHAR(30));
GO
INSERT T1 VALUES ('Row #1');
INSERT T1 (column_2) VALUES ('Row #2');
GO
SET IDENTITY_INSERT T1 ON;
GO
INSERT INTO T1 (column_1,column_2)
VALUES (-99, 'Explicit identity value');
GO
SELECT column_1, column_2
FROM T1;
GO
C. 利用 NEWID() 將資料插入 uniqueidentifier 資料行
下列範例會利用 NEWID() 函數來取得 column_2 的 GUID。這不像識別欄位,Database Engine 並不會如第二個 INSERT 陳述式所示,自動產生 uniqueidentifier 資料類型的資料行值。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1
(
column_1 int IDENTITY,
column_2 uniqueidentifier,
);
GO
INSERT INTO dbo.T1 (column_2)
VALUES (NEWID());
INSERT INTO T1 DEFAULT VALUES;
GO
SELECT column_1, column_2
FROM dbo.T1;
GO
D. 將資料插入使用者定義型別資料行
下列 Transact-SQL 陳述式會將三個資料列插入 Points 資料表的 PointValue 資料行。這個資料行會使用 CLR 使用者定義型別 (UDT)。Point 資料類型包括公開為 UDT 屬性的 X 及 Y 整數值。您必須使用 CAST 或 CONVERT 函數,將以逗號分隔的 X 及 Y 值轉換為 Point 類型。前兩個陳述式使用 CONVERT 函數,將字串值轉換為 Point 類型,而第三個陳述式則使用 CAST 函數。如需詳細資訊,請參閱<操作 UDT 資料>。
INSERT INTO dbo.Points (PointValue) VALUES (CONVERT(Point, '3,4'));
INSERT INTO dbo.Points (PointValue) VALUES (CONVERT(Point, '1,5'));
INSERT INTO dbo.Points (PointValue) VALUES (CAST ('1,99' AS Point));
從其他資料表插入資料
本節的範例示範將一個資料表的資料列插入另一個資料表的方法。
A. 使用 SELECT 和 EXECUTE 選項來插入其他資料表的資料
下列範例會示範如何使用 INSERT…SELECT 或 INSERT…EXECUTE 將一個資料表中的資料插入另一個資料表。每個方法都是以多資料表的 SELECT 陳述式為基礎,而該 SELECT 陳述式在資料行清單中包括一個運算式及一個常值。
第一個 INSERT 陳述式會使用 SELECT 陳述式來擷取來源資料表 (Employee、SalesPerson 和 Person) 中的資料,且會將結果集儲存在 EmployeeSales 資料表中。第二個 INSERT 陳述式會使用 EXECUTE 子句來呼叫包含 SELECT 陳述式的預存程序,而第三個 INSERT 陳述式會使用 EXECUTE 子句將 SELECT 陳述式當做常值字串來參考。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeSales;
GO
IF OBJECT_ID ('dbo.uspGetEmployeeSales', 'P') IS NOT NULL
DROP PROCEDURE uspGetEmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( DataSource varchar(20) NOT NULL,
BusinessEntityID varchar(11) NOT NULL,
LastName varchar(40) NOT NULL,
SalesDollars money NOT NULL
);
GO
CREATE PROCEDURE dbo.uspGetEmployeeSales
AS
SET NOCOUNT ON;
SELECT 'PROCEDURE', sp.BusinessEntityID, c.LastName,
sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE '2%'
ORDER BY sp.BusinessEntityID, c.LastName;
GO
--INSERT...SELECT example
INSERT INTO dbo.EmployeeSales
SELECT 'SELECT', sp.BusinessEntityID, c.LastName, sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE '2%'
ORDER BY sp.BusinessEntityID, c.LastName;
GO
--INSERT...EXECUTE procedure example
INSERT INTO dbo.EmployeeSales
EXECUTE dbo.uspGetEmployeeSales;
GO
--INSERT...EXECUTE('string') example
INSERT INTO dbo.EmployeeSales
EXECUTE
('
SELECT ''EXEC STRING'', sp.BusinessEntityID, c.LastName,
sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID LIKE ''2%''
ORDER BY sp.BusinessEntityID, c.LastName
');
GO
--Show results.
SELECT DataSource,BusinessEntityID,LastName,SalesDollars
FROM dbo.EmployeeSales;
GO
B. 使用 WITH 通用資料表運算式來定義插入的資料
下列範例會建立 NewEmployee 資料表。通用資料表運算式 (EmployeeTemp) 會定義一個或多個資料表中要插入 NewEmployee 資料表的資料列。INSERT 陳述式會在通用資料表運算式中參考此資料行。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL
DROP TABLE HumanResources.NewEmployee;
GO
CREATE TABLE HumanResources.NewEmployee
(
EmployeeID int NOT NULL,
LastName nvarchar(50) NOT NULL,
FirstName nvarchar(50) NOT NULL,
PhoneNumber Phone NULL,
AddressLine1 nvarchar(60) NOT NULL,
City nvarchar(30) NOT NULL,
State nchar(3) NOT NULL,
PostalCode nvarchar(15) NOT NULL,
CurrentFlag Flag
);
GO
WITH EmployeeTemp (EmpID, LastName, FirstName, Phone,
Address, City, StateProvince,
PostalCode, CurrentFlag)
AS (SELECT
e.BusinessEntityID, c.LastName, c.FirstName, pp.PhoneNumber,
a.AddressLine1, a.City, sp.StateProvinceCode,
a.PostalCode, e.CurrentFlag
FROM HumanResources.Employee e
INNER JOIN Person.BusinessEntityAddress AS bea
ON e.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address AS a
ON bea.AddressID = a.AddressID
INNER JOIN Person.PersonPhone AS pp
ON e.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Person.StateProvince AS sp
ON a.StateProvinceID = sp.StateProvinceID
INNER JOIN Person.Person as c
ON e.BusinessEntityID = c.BusinessEntityID
)
INSERT INTO HumanResources.NewEmployee
SELECT EmpID, LastName, FirstName, Phone,
Address, City, StateProvince, PostalCode, CurrentFlag
FROM EmployeeTemp;
GO
C. 使用 TOP 來限制來源資料表中插入的資料
下列範例會使用 TOP 子句來限制從 Employee 資料表插入 NewEmployee 資料表的資料列數。此範例會將 Employee 資料表的第一組隨機的 10 名員工的地址資料插入其中。之後,便會執行 SELECT 陳述式來驗證 NewEmployee 資料表的內容。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL
DROP TABLE HumanResources.NewEmployee;
GO
CREATE TABLE HumanResources.NewEmployee
(
BusinessEntityID int NOT NULL,
LastName nvarchar(50) NOT NULL,
FirstName nvarchar(50) NOT NULL,
PhoneNumber Phone NULL,
AddressLine1 nvarchar(60) NOT NULL,
City nvarchar(30) NOT NULL,
State nchar(3) NOT NULL,
PostalCode nvarchar(15) NOT NULL,
CurrentFlag Flag
);
GO
-- Insert 10 random rows into the table NewEmployee.
INSERT TOP (10) INTO HumanResources.NewEmployee
SELECT
e.BusinessEntityID, c.LastName, c.FirstName, pp.PhoneNumber,
a.AddressLine1, a.City, sp.StateProvinceCode,
a.PostalCode, e.CurrentFlag
FROM HumanResources.Employee e
INNER JOIN Person.BusinessEntityAddress AS bea
ON e.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address AS a
ON bea.AddressID = a.AddressID
INNER JOIN Person.PersonPhone AS pp
ON e.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Person.StateProvince AS sp
ON a.StateProvinceID = sp.StateProvinceID
INNER JOIN Person.Person as c
ON e.BusinessEntityID = c.BusinessEntityID;
GO
SELECT BusinessEntityID, LastName, FirstName, PhoneNumber,
AddressLine1, City, State, PostalCode, CurrentFlag
FROM HumanResources.NewEmployee;
GO
指定標準資料表以外的目標物件
本節的範例示範如何指定檢視表或資料表變數來插入資料列。
A. 指定檢視表來插入資料
下列範例會將檢視表名稱指定為目標物件;不過,新資料列會插入基礎基底資料表中。INSERT 陳述式中的值順序必須符合檢視表的資料行順序。如需詳細資訊,請參閱<透過檢視修改資料>。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
DROP TABLE dbo.T1;
GO
IF OBJECT_ID ('dbo.V1', 'V') IS NOT NULL
DROP VIEW dbo.V1;
GO
CREATE TABLE T1 ( column_1 int, column_2 varchar(30));
GO
CREATE VIEW V1 AS
SELECT column_2, column_1
FROM T1;
GO
INSERT INTO V1
VALUES ('Row 1',1);
GO
SELECT column_1, column_2
FROM T1;
GO
SELECT column_1, column_2
FROM V1;
GO
B. 將資料插入資料表變數
下列範例會將資料表變數指定為目標物件。
USE AdventureWorks2008R2;
GO
-- Create the table variable.
DECLARE @MyTableVar table(
LocationID int NOT NULL,
CostRate smallmoney NOT NULL,
NewCostRate AS CostRate * 1.5,
ModifiedDate datetime);
-- Insert values into the table variable.
INSERT INTO @MyTableVar (LocationID, CostRate, ModifiedDate)
SELECT LocationID, CostRate, GETDATE() FROM Production.Location
WHERE CostRate > 0;
-- View the table variable result set.
SELECT * FROM @MyTableVar;
GO
將資料列插入遠端資料表
本節的範例示範如何將資料列插入遠端目標資料表中,其方式是使用連結的伺服器或資料列集函數參考遠端資料表。
A. 使用連結的伺服器將資料插入遠端資料表
下列範例會將資料列插入遠端資料表。此範例一開始會使用 sp_addlinkedserver 建立遠端資料來源的連結。然後會將連結的伺服器名稱 MyLinkServer 指定為 server.catalog.schema.object 格式之四部分物件名稱的一部分。
USE master;
GO
-- Create a link to the remote data source.
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.
EXEC sp_addlinkedserver @server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI',
@datasrc = N'server_name',
@catalog = N'AdventureWorks2008R2';
GO
USE AdventureWorks2008R2;
GO
-- Specify the remote data source in the FROM clause using a four-part name
-- in the form linked_server.catalog.schema.object.
INSERT INTO MyLinkServer.AdventureWorks2008R2.HumanResources.Department (Name, GroupName)
VALUES (N'Public Relations', N'Executive General and Administration');
GO
B. 使用 OPENQUERY 函數將資料插入遠端資料表
下列範例會藉由指定 OPENQUERY 資料列集函數將資料列插入遠端資料表。上一個範例所建立之連結的伺服器名稱會用於這個範例。
-- Use the OPENQUERY function to access the remote data source.
INSERT OPENQUERY (MyLinkServer, 'SELECT Name, GroupName FROM AdventureWorks2008R2.HumanResources.Department')
VALUES ('Environmental Impact', 'Engineering');
GO
C. 使用 OPENDATASOURCE 函數將資料插入遠端資料表
下列範例會藉由指定 OPENDATASOURCE 資料列集函數將資料列插入遠端資料表。請使用 server_name 或 server_name\instance_name 格式,為資料來源指定有效的伺服器名稱。
-- Use the OPENDATASOURCE function to specify the remote data source.
-- Specify a valid server name for Data Source using the format server_name or server_name\instance_name.
INSERT INTO OPENDATASOURCE('SQLNCLI',
'Data Source= <server_name>; Integrated Security=SSPI')
.AdventureWorks2008R2.HumanResources.Department (Name, GroupName)
VALUES (N'Standards and Methods', 'Quality Assurance');
GO
大量匯入資料表或資料檔案中的資料
本節的範例示範利用 INSERT 陳述式將資料大量匯入 (大量載入) 資料表中的兩個方法。
A. 使用最低限度記錄,將資料插入堆積中
下列範例會建立新的資料表 (堆積),然後使用最低限度記錄,將另一個資料表中的資料插入其中。此範例會假設 AdventureWorks2008R2 資料庫的復原模式設定為 FULL。為了確保使用最低限度記錄,AdventureWorks2008R2 資料庫的復原模式會在插入資料列之前設定為 BULK_LOGGED,然後在 INSERT INTO…SELECT 陳述式之後重設為 FULL。此外,針對目標資料表 Sales.SalesHistory 指定了 TABLOCK 提示。這樣做可確保此陳述式會在交易記錄中使用最小的空間並有效率地執行作業。
USE AdventureWorks2008R2;
GO
-- Create the target heap.
CREATE TABLE Sales.SalesHistory(
SalesOrderID int NOT NULL,
SalesOrderDetailID int NOT NULL,
CarrierTrackingNumber nvarchar(25) NULL,
OrderQty smallint NOT NULL,
ProductID int NOT NULL,
SpecialOfferID int NOT NULL,
UnitPrice money NOT NULL,
UnitPriceDiscount money NOT NULL,
LineTotal money NOT NULL,
rowguid uniqueidentifier ROWGUIDCOL NOT NULL,
ModifiedDate datetime NOT NULL );
GO
-- Temporarily set the recovery model to BULK_LOGGED.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY BULK_LOGGED;
GO
-- Transfer data from Sales.SalesOrderDetail to Sales.SalesHistory
INSERT INTO Sales.SalesHistory WITH (TABLOCK)
(SalesOrderID,
SalesOrderDetailID,
CarrierTrackingNumber,
OrderQty,
ProductID,
SpecialOfferID,
UnitPrice,
UnitPriceDiscount,
LineTotal,
rowguid,
ModifiedDate)
SELECT * FROM Sales.SalesOrderDetail;
GO
-- Reset the recovery model.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY FULL;
GO
B. 搭配 BULK 使用 OPENROWSET 函數,將資料大量匯入資料表
下列範例會藉由指定 OPENROWSET 函數,將資料檔案中的資料列插入資料表。將會指定 IGNORE_TRIGGERS 資料表提示來讓效能最佳化。如需其他範例,請參閱<使用 BULK INSERT 或 OPENROWSET(BULK...) 匯入大量資料>。
-- Use the OPENROWSET function to specify the data source and specifies the IGNORE_TRIGGERS table hint.
INSERT INTO HumanResources.Department WITH (IGNORE_TRIGGERS) (Name, GroupName)
SELECT b.Name, b.GroupName
FROM OPENROWSET (
BULK 'C:\SQLFiles\DepartmentData.txt',
FORMATFILE = 'C:\SQLFiles\BulkloadFormatFile.xml',
ROWS_PER_BATCH = 15000)AS b ;
GO
使用提示來覆寫查詢最佳化工具的預設行為
本節的範例示範如何使用資料表提示,在處理 INSERT 陳述式時暫時覆寫查詢最佳化工具的預設行為。
注意 |
---|
由於 SQL Server 查詢最佳化工具通常會選取最好的查詢執行計畫,因此,我們建議資深的開發人員和資料庫管理員將提示當做最後的解決辦法。 |
A. 使用 TABLOCK 提示來指定鎖定方法
下列範例指定在 Production.Location 資料表上採用獨佔 (X) 鎖定,並且將鎖定保留到 INSERT 陳述式結束為止。
USE AdventureWorks2008R2;
GO
INSERT INTO Production.Location WITH (XLOCK)
(Name, CostRate, Availability)
VALUES ( N'Final Inventory', 15.00, 80.00);
GO
擷取 INSERT 陳述式的結果
本節的範例示範如何使用 OUTPUT 子句傳回 INSERT 陳述式所影響之每個資料列的資訊,或是以該資料列為根據的運算式。這些結果可以傳回給負責處理的應用程式,以便用在確認訊息、封存或其他這類應用程式需求等用途上。
A. 搭配 INSERT 陳述式使用 OUTPUT
下列範例會將資料列插入 ScrapReason 資料表中,並且利用 OUTPUT 子句,將陳述式的結果傳回給 @MyTableVar 資料表變數。由於 ScrapReason 資料表中的 ScrapReasonID 資料行已定義了 IDENTITY 屬性,因此 INSERT 陳述式不會指定值給該資料行。不過,請注意,Database Engine 針對這個資料行所產生的值會在 INSERTED.ScrapReasonID 資料行的 OUTPUT 子句中傳回。
USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID 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 NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate
FROM Production.ScrapReason;
GO
B. 搭配識別欄位和計算資料行使用 OUTPUT
下列範例會建立 EmployeeSales 資料表,之後再利用含有 SELECT 陳述式的 INSERT 陳述式來擷取來源資料表中的資料,以插入幾個資料列。EmployeeSales 資料表包含一個識別欄位 (EmployeeID) 和一個計算資料行 (ProjectedSales)。由於這些值都是 Database Engine 在插入作業期間所產生的,因此,這些資料行都不能定義在 @MyTableVar 中。
USE AdventureWorks2008R2 ;
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 Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.BusinessEntityID 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
C. 插入從 OUTPUT 子句傳回的資料
下列範例將擷取從 MERGE 陳述式的 OUTPUT 子句中傳回的資料,並將該資料插入另一個資料表中。MERGE 陳述式會根據在 SalesOrderDetail 資料表中處理的順序,每天更新 ProductInventory 資料表的 Quantity 資料行。它也會刪除產品存貨降到 0 的資料列。此範例會擷取已刪除的資料列,並將其插入另一個資料表 ZeroInventory,該資料表會追蹤沒有存貨的產品。
USE AdventureWorks2008R2;
GO
IF OBJECT_ID(N'Production.ZeroInventory', N'U') IS NOT NULL
DROP TABLE Production.ZeroInventory;
GO
--Create ZeroInventory table.
CREATE TABLE Production.ZeroInventory (DeletedProductID int, RemovedOnDate DateTime);
GO
INSERT INTO Production.ZeroInventory (DeletedProductID, RemovedOnDate)
SELECT ProductID, GETDATE()
FROM
( MERGE Production.ProductInventory AS pi
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod
JOIN Sales.SalesOrderHeader AS soh
ON sod.SalesOrderID = soh.SalesOrderID
AND soh.OrderDate = '20070401'
GROUP BY ProductID) AS src (ProductID, OrderQty)
ON (pi.ProductID = src.ProductID)
WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0
THEN DELETE
WHEN MATCHED
THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty
OUTPUT $action, deleted.ProductID) AS Changes (Action, ProductID)
WHERE Action = 'DELETE';
IF @@ROWCOUNT = 0
PRINT 'Warning: No rows were inserted';
GO
SELECT DeletedProductID, RemovedOnDate FROM Production.ZeroInventory;