INSERT の例 (Transact-SQL)

ここでは、SQL Server 2008 R2 での Transact-SQL INSERT ステートメントの使用例を紹介します。INSERT の使用例は以下のカテゴリに分けられています。

カテゴリ

主な構文要素

基本構文

INSERT • テーブル値コンストラクター

列の値を処理する

IDENTITY • NEWID • 既定値 • ユーザー定義型

他のテーブルのデータを挿入する

INSERT…SELECT • INSERT…EXECUTE • WITH 共通テーブル式 • TOP

標準的なテーブル以外の対象オブジェクトを指定する

ビュー • テーブル変数

リモート テーブルに行を挿入する

リンク サーバー • OPENQUERY 行セット関数 • OPENDATASOURCE 行セット関数

テーブルまたはデータ ファイルのデータの一括インポートを行う

INSERT…SELECT • OPENROWSET 関数

ヒントを使用してクエリ オプティマイザーの既定の動作を上書きする

テーブル ヒント

INSERT ステートメントの結果をキャプチャする

OUTPUT 句

基本構文

このセクションの例では、最低限必要な構文を使用して INSERT ステートメントの基本機能を示します。

A. 1 行のデータを挿入する

次の例では、Production.UnitMeasure テーブルに 1 行を挿入します。このテーブルの列は、UnitMeasureCode、Name、および ModifiedDate です。すべての列の値が指定され、テーブルの列と同じ順序で並んでいるため、列名を列リストで指定する必要はありません。

USE AdventureWorks2008R2;
GO
INSERT INTO Production.UnitMeasure
VALUES (N'FT', N'Feet', '20080414');
GO

B. 複数行のデータを挿入する

次の例では、単一の INSERT ステートメントでテーブル値コンストラクターを使用して、Production.UnitMeasure テーブルに 3 行を挿入します。すべての列の値が指定され、テーブルの列と同じ順序で並んでいるため、列名を列リストで指定する必要はありません。

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 データ型で定義されており、一意の増分する 2 進数を自動的に生成します。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. ID 列を持つテーブルにデータを挿入する

次の例では、ID 列にデータを挿入する方法をいくつか示します。最初の 2 つの INSERT ステートメントで、新規の行に対して ID 値が生成されます。3 番目の INSERT ステートメントは、SET IDENTITY_INSERT ステートメントで設定された列の IDENTITY プロパティを上書きし、ID 列に値を明示的に挿入します。

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 を取得します。ID 列とは異なり、データベース エンジンでは uniqueidentifier 型の列に対して自動的に値が生成されません。2 番目の INSERT ステートメントを参照してください。

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 列に 3 行を挿入します。この列は、CLR ユーザー定義型 (UDT) を使用しています。Point データ型は、UDT のプロパティとして公開されている整数値 X と Y で構成されます。コンマ区切りの X と Y の値を Point 型にキャストするには、CAST 関数または CONVERT 関数のいずれかを使用する必要があります。最初の 2 つのステートメントでは、CONVERT 関数を使用し、3 つ目のステートメントでは 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 ステートメントに基づきます。

1 番目の INSERT ステートメントでは、SELECT ステートメントを使用してソース テーブル (Employee、SalesPerson、および Person) からデータを取得し、その結果セットを EmployeeSales テーブルに格納します。2 番目の INSERT ステートメントは、EXECUTE 句を使用して SELECT ステートメントを含むストアド プロシージャを呼び出します。3 番目の 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 テーブルに挿入する 1 つ以上のテーブルの行を定義します。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 テーブルに挿入される行の数を制限します。この例では、 テーブルからランダムに選択した 10 人の従業員の住所データを NewEmployee テーブルに挿入します。次に、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 を使用してリモート データ ソースへのリンクを作成した後、server.catalog.schema.object という形式の 4 部構成のオブジェクト名の一部として、リンク サーバー名 MyLinkServer を指定します。

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 ステートメントを使用してテーブルにデータを一括インポート (一括読み込み) する 2 つの方法を示します。

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. OPENROWSET 関数を BULK を指定して使用し、テーブルにデータを一括インポートする

次の例では、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. OUTPUT を INSERT ステートメントで使用する

次の例では、ScrapReason テーブルに 1 行を挿入し、OUTPUT 句を使用してステートメントの結果を @MyTableVar テーブル変数に返します。ScrapReason テーブルの ScrapReasonID 列が IDENTITY プロパティで定義されているため、INSERT ステートメントではこの列の値を指定していません。ただし、データベース エンジンによってこの列用に生成された値が、OUTPUT 句で INSERTED.ScrapReasonID 列に返されます。

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. ID 列と計算列で OUTPUT を使用する

次の例では、EmployeeSales テーブルを作成し、INSERT ステートメントを使用してこのテーブルに複数行を挿入します。基になるテーブルからデータを取得するため、SELECT ステートメントも使用します。EmployeeSales テーブルには、ID 列 (EmployeeID) および計算列 (ProjectedSales) があります。これらの値はデータベース エンジンによって挿入操作中に生成されるため、いずれの列も @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;