Примеры использования инструкции INSERT (Transact-SQL)

В этом разделе приведены примеры использования инструкции Transact-SQL INSERT в SQL Server 2008 R2. Примеры использования инструкции INSERT сгруппированы по следующим категориям.

Категория

Используемые элементы синтаксиса

Базовый синтаксис

INSERT • конструктор табличных значений

Обработка значений столбца

IDENTITY • NEWID • значения по умолчанию • определяемые пользователем типы

Вставка данных из других таблиц

INSERT…SELECT • INSERT…EXECUTE • WITH обобщенное табличное выражение • TOP

Указание целевых объектов, отличных от стандартных таблиц

Представления • табличные переменные

Вставка строк в удаленную таблицу

Связанный сервер • OPENQUERY, функция набора строк • OPENDATASOURCE, функция набора строк

Массовый импорт данных из таблиц или файлов данных

INSERT…SELECT • OPENROWSET, функция

Переопределение поведения по умолчанию оптимизатора запросов с помощью подсказок

Табличные подсказки

Сбор результатов инструкции INSERT

OUTPUT, предложение

Базовый синтаксис

В примерах в этом разделе описывается базовая функциональность инструкции INSERT с помощью минимального необходимого синтаксиса.

А. Вставка одной строки данных

В следующем примере в таблицу Production.UnitMeasure вставляется одна строка. В этой таблице содержатся столбцы UnitMeasureCode, Name и ModifiedDate. Так как значения для всех столбцов предоставлены и перечислены в том же порядке, что и столбцы в таблице, то имена столбцов не нужно указывать в списке столбцов.


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

Б. Вставка нескольких строк данных

В следующем примере конструктор табличных значений используется для вставки трех строк в таблицу Production.UnitMeasure одной инструкцией INSERT. Так как значения для всех столбцов предоставлены и перечислены в том же порядке, что и столбцы в таблице, то не нужно в параметре указывать имена столбцов.


    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

В. Вставка данных в порядке, отличном от порядка столбцов таблицы

В следующем примере используется список столбцов для явного указания значений, которые будут вставляться в каждый столбец. В таблице 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, или столбцов определяемого пользователем типа.

А. Вставка данных в таблицу со столбцами, имеющими значение по умолчанию

В следующем примере описывается вставка строк в таблицу со столбцами, автоматически создающими значение, или имеющими значение по умолчанию. Column_1 представляет собой вычисляемый столбец, автоматически формирующий значения путем объединения строки со значением, вставляемым в столбец 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

Б. Вставка данных в таблицу со столбцом идентификаторов

В следующем примере показаны различные методы вставки данных в столбец идентификаторов. Первые две инструкции INSERT позволяют формировать значения идентификаторов для новых строк. Третья инструкция INSERT переопределяет свойство IDENTITY столбца с помощью инструкции SET IDENTITY_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 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

В. Вставка данных в столбец уникального идентификатора с помощью функции NEWID()

В следующем примере функция NEWID() вызывается для вставки идентификатора GUID в столбец column_2. В отличие от столбцов идентификаторов, компонент Database Engine не создает автоматически значения для столбцов с типом данных uniqueidentifier, как показано во второй инструкции 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

Г. Вставка данных в столбцы определяемого пользователем типа

Следующие инструкции Transact-SQL вставляют три строки в столбец PointValue таблицы Points. Этот столбец имеет определяемый пользователем тип данных CLR. Тип данных Point состоит из целочисленных значений X и Y, которые представлены как свойства определяемого пользователем типа. Необходимо привести разделяемые запятой значения X и Y к типу Point с помощью функции CAST или CONVERT. Первые две инструкции используют функцию CONVERT для преобразования строкового значения в тип Point, а третья инструкция использует функцию CAST. Дополнительные сведения см. в разделе Работа с данными определяемого пользователем типа.

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));

Вставка данных из других таблиц

В примерах этого раздела показаны методы вставки строк из одной таблицы в другую.

А. Вставка данных из других таблиц с помощью параметров SELECT и EXECUTE

В следующем примере описана вставка данных из одной таблицы в другую с помощью инструкций INSERT…SELECT и INSERT…EXECUTE. Каждый метод основан на многотабличной инструкции 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

Б. Использование обобщенного табличного выражения 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

В. Использование TOP для ограничения данных, вставляемых из исходной таблицы

В следующем примере используется предложение TOP для ограничения числа строк, вставляемых в таблицу NewEmployee из таблицы Employee. В примере вставляются данные адреса первых 10 произвольно выбранных сотрудников из таблицы Employee. Затем выполняется инструкция 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

Указание целевых объектов, отличных от стандартных таблиц

В примерах этого раздела показаны методы вставки строк с указанием представления или табличной переменной.

А. Вставка данных с указанием представления

В следующем примере в качестве целевого объекта указано имя представления; новая строка вставляется в базовую таблицу. Порядок следования значений в инструкции 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

Б. Вставка данных в табличную переменную

В следующем примере в качестве целевого объекта указана табличная переменная.

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  

Вставка строк в удаленную таблицу

В примерах в этом разделе описаны способы вставки в удаленную целевую таблицу с использованием в качестве ссылки на удаленную таблицу связанного сервера или функции, возвращающей набор строк.

А. Вставка данных в удаленную таблицу с использованием связанного сервера

В следующем примере в удаленную таблицу вставляются строки. Этот пример начинается с создания ссылки на удаленный источник данных с помощью хранимой процедуры 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

Б. Вставка данных в удаленную таблицу с помощью функции 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

В. Вставка данных в удаленную таблицу с помощью функции 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.

А. Вставка данных в кучу с минимальным протоколированием

В следующем примере создается новая таблица (куча), в которую вставляются данные из другой таблицы с минимальным протоколированием. В примере предполагается, что для базы данных База данных 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

Б. Использование функции OPENROWSET с BULK для массового импорта данных а таблицу

В следующем примере выполняется вставка строки в таблицу из файла данных вызовом функции OPENQUERY. Для оптимизации производительности указывается табличная подсказка 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 обычно выбирает наилучший план выполнения запроса, подсказки рекомендуется использовать только опытным разработчикам и администраторам баз данных в качестве последнего средства.

А. Использование подсказки TABLOCK для указания метода блокировки

В следующем примере показано, как монопольная блокировка (Х) применяется к таблице Production.Location и сохраняется до завершения инструкции INSERT.


    USE AdventureWorks2008R2;
    GO
    INSERT INTO Production.Location WITH (XLOCK)
    (Name, CostRate, Availability)
    VALUES ( N'Final Inventory', 15.00, 80.00);
    GO

Сбор результатов инструкции INSERT

Примеры в этом разделе описывают использование предложения OUTPUT для возврата данных для всех строк, изменившихся в результате выполнения инструкции, либо выражений на основе этих данных. Эти результаты могут быть возвращены приложению, например для вывода подтверждающих сообщений, архивирования и т. п.

А. Использование предложения OUTPUT с инструкцией INSERT

В следующем примере производится вставка строки в таблицу ScrapReason, а затем при помощи предложения OUTPUT результаты выполнения инструкции возвращаются в табличную переменную @MyTableVar. Поскольку столбец ScrapReasonID в таблице ScrapReason определен со свойством IDENTITY, в инструкции INSERT его значение для этого столбца не указывается. Обратите внимание, что значение, которое компонент Database Engine сформировал для этого столбца, возвращается предложением 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

Б. Применение предложения OUTPUT со столбцами идентификаторов и вычисляемыми столбцами

В следующем примере создается таблица EmployeeSales, а затем в нее с помощью инструкции INSERT вставляется несколько строк, получаемых инструкцией SELECT из исходных таблиц. Таблица 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

В. Вставка данных, возвращенных предложением OUTPUT

В следующем примере производится отслеживание данных, возвращаемых предложением OUTPUT инструкции MERGE, а затем производится вставка этих данных в другую таблицу. Инструкция MERGE ежедневно обновляет столбец Quantity таблицы ProductInventory в соответствии с заказами, обрабатываемыми в таблице SalesOrderDetail. Инструкция также удаляет строки с продуктами, запас которых сократился до 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;