Предложение OUTPUT (Transact-SQL)OUTPUT Clause (Transact-SQL)

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server даБаза данных SQL Azure нетAzure Synapse Analytics (хранилище данных SQL) нетParallel Data WarehouseAPPLIES TO: yesSQL Server yesAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

Возвращает данные из строк, изменившихся в результате выполнения инструкций INSERT, UPDATE, DELETE или MERGE, или выражения на основе этих данных.Returns information from, or expressions based on, each row affected by an INSERT, UPDATE, DELETE, or MERGE statement. Эти результаты могут быть возвращены приложению, например для вывода подтверждающих сообщений, архивирования и т. п.These results can be returned to the processing application for use in such things as confirmation messages, archiving, and other such application requirements. Результаты также могут быть вставлены в таблицу или табличную переменную.The results can also be inserted into a table or table variable. Кроме того, можно записать результаты предложения OUTPUT во вложенных инструкциях INSERT, UPDATE, DELETE или MERGE и вставить эти результаты в целевую таблицу или представление.Additionally, you can capture the results of an OUTPUT clause in a nested INSERT, UPDATE, DELETE, or MERGE statement, and insert those results into a target table or view.

Примечание

Инструкция UPDATE, INSERT или DELETE с предложением OUTPUT возвращает строки клиенту даже в случае, если при выполнении инструкции возникли ошибки и был выполнен ее откат.An UPDATE, INSERT, or DELETE statement that has an OUTPUT clause will return rows to the client even if the statement encounters errors and is rolled back. Результат не может быть использован, если при выполнении инструкции возникли какие-либо ошибки.The result should not be used if any error occurs when you run the statement.

Применяется в:Used in:

DELETEDELETE

INSERTINSERT

UPDATEUPDATE

MERGEMERGE

Значок ссылки на раздел Синтаксические обозначения в Transact-SQLTopic link icon Transact-SQL Syntax Conventions

СинтаксисSyntax

  
<OUTPUT_CLAUSE> ::=  
{  
    [ OUTPUT <dml_select_list> INTO { @table_variable | output_table } [ ( column_list ) ] ]  
    [ OUTPUT <dml_select_list> ]  
}  
<dml_select_list> ::=  
{ <column_name> | scalar_expression } [ [AS] column_alias_identifier ]  
    [ ,...n ]  
  
<column_name> ::=  
{ DELETED | INSERTED | from_table_name } . { * | column_name }  
    | $action  

АргументыArguments

@table_variable@table_variable
Указывает переменную table, в которую возвращенные строки вставляются вместо передачи вызывающему приложению.Specifies a table variable that the returned rows are inserted into instead of being returned to the caller. Аргумент @table_variable необходимо объявить перед вызовом инструкции INSERT, UPDATE, DELETE или MERGE.@table_variable must be declared before the INSERT, UPDATE, DELETE, or MERGE statement.

Если не указан аргумент column_list, переменная table должна иметь то же число столбцов, что и результирующий набор OUTPUT,If column_list is not specified, the table variable must have the same number of columns as the OUTPUT result set. за исключением столбцов идентификаторов и вычисляемых столбцов, которые следует пропустить.The exceptions are identity and computed columns, which must be skipped. Если аргумент column_list указан, то любые пропущенные столбцы должны либо допускать значение NULL, либо для них должны быть определены значения по умолчанию.If column_list is specified, any omitted columns must either allow null values or have default values assigned to them.

Дополнительные сведения о переменных типа table см. в статье table (Transact-SQL).For more information about table variables, see table (Transact-SQL).

output_tableoutput_table
Указывает таблицу, в которую возвращенные строки вставляются вместо передачи вызывающему приложению.Specifies a table that the returned rows are inserted into instead of being returned to the caller. Таблица output_table может быть временной.output_table may be a temporary table.

Если аргумент column_list не указан, то таблица должна иметь то же число столбцов, что и результирующий набор OUTPUT,If column_list is not specified, the table must have the same number of columns as the OUTPUT result set. за исключением столбцов идентификаторов и вычисляемых столбцов.The exceptions are identity and computed columns. Эти столбцы следует пропустить.These must be skipped. Если аргумент column_list указан, то любые пропущенные столбцы должны либо допускать значение NULL, либо для них должны быть определены значения по умолчанию.If column_list is specified, any omitted columns must either allow null values or have default values assigned to them.

Таблица output_table не может:output_table cannot:

  • Иметь включенные триггеры, определенные для нее.Have enabled triggers defined on it.

  • Участвовать в ограничениях FOREIGN KEY с любой стороны.Participate on either side of a FOREIGN KEY constraint.

  • Иметь ограничения CHECK или активированные правила.Have CHECK constraints or enabled rules.

column_listcolumn_list
Необязательный список имен столбцов для целевой таблицы, указанной в предложении INTO.Is an optional list of column names on the target table of the INTO clause. Он аналогичен списку столбцов, указываемому в инструкции INSERT.It is analogous to the column list allowed in the INSERT statement.

scalar_expressionscalar_expression
Любое сочетание символов и операторов, результатом вычисления которого является единственное значение.Is any combination of symbols and operators that evaluates to a single value. Агрегатные функции в scalar_expression указывать нельзя.Aggregate functions are not permitted in scalar_expression.

Ссылки на изменяемые столбцы таблицы должны предваряться префиксом INSERTED или DELETED.Any reference to columns in the table being modified must be qualified with the INSERTED or DELETED prefix.

column_alias_identifiercolumn_alias_identifier
Альтернативное имя, используемое для указания ссылок на этот столбец.Is an alternative name used to reference the column name.

DELETEDDELETED
Префикс столбца, который указывает на значение, удаляемое в результате выполнения операции обновления или удаления.Is a column prefix that specifies the value deleted by the update or delete operation. Столбцы, имеющие префикс DELETED, отражают значение, которое было до завершения инструкции UPDATE, DELETE или MERGE.Columns prefixed with DELETED reflect the value before the UPDATE, DELETE, or MERGE statement is completed.

Префикс DELETED не может указываться вместе с предложением OUTPUT в инструкции INSERT.DELETED cannot be used with the OUTPUT clause in the INSERT statement.

INSERTEDINSERTED
Префикс столбца, который указывает на значение, добавляемое в результате выполнении операции вставки или обновления.Is a column prefix that specifies the value added by the insert or update operation. Столбцы, имеющие префикс INSERTED, отражают значение, полученное после завершения инструкции UPDATE, INSERT или MERGE, но до выполнения триггеров.Columns prefixed with INSERTED reflect the value after the UPDATE, INSERT, or MERGE statement is completed but before triggers are executed.

Префикс INSERTED не может указываться вместе с предложением OUTPUT в инструкции DELETE.INSERTED cannot be used with the OUTPUT clause in the DELETE statement.

from_table_namefrom_table_name
Префикс столбца, который обозначает таблицу, содержащуюся в предложении FROM инструкции DELETE, UPDATE или MERGE; эти инструкции указывают обновляемые или удаляемые строки.Is a column prefix that specifies a table included in the FROM clause of a DELETE, UPDATE, or MERGE statement that is used to specify the rows to update or delete.

Если изменяемая таблица указана также и в предложении FROM, все ссылки на столбцы, содержащиеся в этой таблице, должны предваряться префиксом INSERTED или DELETED.If the table being modified is also specified in the FROM clause, any reference to columns in that table must be qualified with the INSERTED or DELETED prefix.

*
Указывает, что все столбцы, участвующие в операции удаления, вставки или обновления, возвращаются в том порядке, в котором они существуют в таблице.Specifies that all columns affected by the delete, insert, or update action will be returned in the order in which they exist in the table.

Например, в следующей инструкции DELETE предложение OUTPUT DELETED.* возвращает все столбцы, удаленные из таблицы ShoppingCartItem:For example, OUTPUT DELETED.* in the following DELETE statement returns all columns deleted from the ShoppingCartItem table:

DELETE Sales.ShoppingCartItem  
    OUTPUT DELETED.*;  

column_namecolumn_name
Явное указание столбца.Is an explicit column reference. Любая ссылка на изменяемую таблицу должна предваряться соответствующим префиксом INSERTED или DELETED, например: INSERTED . столбец_имя.Any reference to the table being modified must be correctly qualified by either the INSERTED or the DELETED prefix as appropriate, for example: INSERTED .column_name.

$action$action
Доступен только для инструкции MERGE.Is available only for the MERGE statement. Указывает столбец типа nvarchar(10) в предложении OUTPUT инструкции MERGE, которая возвращает одно из трех значений для каждой строки: INSERT, UPDATE или DELETE — согласно действию, которое было выполнено с этой строкой.Specifies a column of type nvarchar(10) in the OUTPUT clause in a MERGE statement that returns one of three values for each row: 'INSERT', 'UPDATE', or 'DELETE', according to the action that was performed on that row.

RemarksRemarks

Предложения OUTPUT <dml_select_list> clause and the OUTPUT <dml_select_list> INTO { @ table_variable | output_table } можно определить в одной инструкции INSERT, UPDATE, DELETE или MERGE.The OUTPUT <dml_select_list> clause and the OUTPUT <dml_select_list> INTO { @table_variable | output_table } clause can be defined in a single INSERT, UPDATE, DELETE, or MERGE statement.

Примечание

Если не указано иное, ссылки на предложение OUTPUT относятся как к предложению OUTPUT, так и к предложению OUTPUT INTO.Unless specified otherwise, references to the OUTPUT clause refer to both the OUTPUT clause and the OUTPUT INTO clause.

Применение предложения OUTPUT может оказаться полезным при получении значения идентификаторов или вычисляемых столбцов после выполнения операций INSERT и UPDATE.The OUTPUT clause may be useful to retrieve the value of identity or computed columns after an INSERT or UPDATE operation.

Если вычисляемый столбец включен в <dml_select_list>, то соответствующий столбец в выходной таблице или табличной переменной вычисляемым не является.When a computed column is included in the <dml_select_list>, the corresponding column in the output table or table variable is not a computed column. В него будет помещено значение, вычисленное в момент выполнения инструкции.The values in the new column are the values that were computed at the time the statement was executed.

Нет никакой гарантии, что порядок, в котором изменения применяются к таблице, будет соответствовать порядку, в котором строки вставляются в выводную таблицу или табличную переменную.There is no guarantee that the order in which the changes are applied to the table and the order in which the rows are inserted into the output table or table variable will correspond.

Если параметры или переменные изменяются при выполнении инструкции UPDATE, предложение OUTPUT всегда возвращает значение параметра или переменной, которое было актуально до выполнения этой инструкции, а не измененное значение.If parameters or variables are modified as part of an UPDATE statement, the OUTPUT clause always returns the value of the parameter or variable as it was before the statement executed instead of the modified value.

Предложение OUTPUT можно указывать с инструкциями UPDATE и DELETE, применяемыми к курсору с использованием синтаксиса WHERE CURRENT OF.You can use OUTPUT with an UPDATE or DELETE statement positioned on a cursor that uses WHERE CURRENT OF syntax.

Предложение OUTPUT не поддерживается для:The OUTPUT clause is not supported in the following statements:

  • Инструкций DML, которые содержат ссылки на локальные секционированные представления, распределенные секционированные представления или удаленные таблицы.DML statements that reference local partitioned views, distributed partitioned views, or remote tables.

  • Инструкций INSERT, содержащих инструкции EXECUTE.INSERT statements that contain an EXECUTE statement.

  • Полнотекстовые предикаты не допускаются в предложении OUTPUT, если уровень совместимости базы данных установлен в 100.Full-text predicates are not allowed in the OUTPUT clause when the database compatibility level is set to 100.

  • Предложение OUTPUT INTO не может быть использовано для вставки строк в представление или функцию, возвращающую набор строк.The OUTPUT INTO clause cannot be used to insert into a view, or rowset function.

  • Определяемая пользователем функция не может быть создана, если в ней содержится предложение OUTPUT INTO, имеющее в качестве цели таблицу.A user-defined function cannot be created if it contains an OUTPUT INTO clause that has a table as its target.

Чтобы предотвратить недетерминированное поведение, в предложении OUTPUT не могут содержаться следующие ссылки.To prevent nondeterministic behavior, the OUTPUT clause cannot contain the following references:

  • Вложенные запросы или определяемые пользователем функции, которые обеспечивают (или предположительно обеспечивают) пользовательский или системный доступ к данным.Subqueries or user-defined functions that perform user or system data access, or are assumed to perform such access. Предполагается, что определяемые пользователем функции выполняют доступ к данным, если они не привязаны к схеме.User-defined functions are assumed to perform data access if they are not schema-bound.

  • Столбец из представления или встроенная функция с табличным значением, если этот столбец определяется с помощью одного из следующих методов.A column from a view or inline table-valued function when that column is defined by one of the following methods:

    • вложенный запрос.A subquery.

    • Определяемая пользователем функция, которая осуществляет или может осуществлять доступ к пользовательским или системным данным.A user-defined function that performs user or system data access, or is assumed to perform such access.

    • Вычисляемый столбец, содержащий определяемую пользователем функцию, которая осуществляет доступ к пользовательским или системным данным в своем определении.A computed column that contains a user-defined function that performs user or system data access in its definition.

    При обнаружении SQL ServerSQL Server такого столбца в предложении OUTPUT возвращается ошибка 4186.When SQL ServerSQL Server detects such a column in the OUTPUT clause, error 4186 is raised.

Вставка в таблицу данных, которые были возвращены предложением OUTPUTInserting Data Returned From an OUTPUT Clause Into a Table

При сборе результатов предложения OUTPUT во вложенных инструкциях INSERT, UPDATE, DELETE или MERGE и вставки этих результатов в целевую таблицу или представление необходимо учитывать следующее.When you are capturing the results of an OUTPUT clause in a nested INSERT, UPDATE, DELETE, or MERGE statement and inserting those results into a target table, keep the following information in mind:

  • Вся операция является атомарной.The whole operation is atomic. Или инструкция INSERT выполняется вместе с вложенной инструкцией DML, содержащей предложение OUTPUT, или выполнение всей инструкции завершается с ошибкой.Either both the INSERT statement and the nested DML statement that contains the OUTPUT clause execute, or the whole statement fails.

  • К целевому объекту внешней инструкции INSERT применяются следующие ограничения.The following restrictions apply to the target of the outer INSERT statement:

    • Целевой объект не должен быть удаленной таблицей, представлением или обобщенным табличным выражением.The target cannot be a remote table, view, or common table expression.

    • Целевой объект не должен иметь ограничения FOREIGN KEY либо быть объектом ссылки ограничения FOREIGN KEY.The target cannot have a FOREIGN KEY constraint, or be referenced by a FOREIGN KEY constraint.

    • Триггеры не должны быть определены на целевом объекте.Triggers cannot be defined on the target.

    • Целевой объект не должен участвовать в репликации слиянием или обновляемых подписках для репликации транзакций.The target cannot participate in merge replication or updatable subscriptions for transactional replication.

  • К вложенной инструкции DML применяются следующие ограничения.The following restrictions apply to the nested DML statement:

    • Целевой объект не должен быть удаленной таблицей или секционированным представлением.The target cannot be a remote table or partitioned view.

    • Сам источник не должен содержать предложение <dml_table_source>.The source itself cannot contain a <dml_table_source> clause.

  • Предложение OUTPUT INTO не поддерживается в инструкциях INSERT, содержащих предложение <dml_table_source>.The OUTPUT INTO clause is not supported in INSERT statements that contain a <dml_table_source> clause.

  • @@ROWCOUNT возвращает только строки, вставленные внешней инструкцией INSERT.@@ROWCOUNT returns the rows inserted only by the outer INSERT statement.

  • @@IDENTITY, SCOPE_IDENTITY и IDENT_CURRENT возвращают значения идентификаторов, созданные не внешней инструкцией INSERT, а только вложенной инструкцией DML.@@IDENTITY, SCOPE_IDENTITY, and IDENT_CURRENT return identity values generated only by the nested DML statement, and not those generated by the outer INSERT statement.

  • Уведомления о запросах рассматривают инструкцию как единую сущность, и тип любого созданного сообщения будет типом вложенной инструкции DML, даже если внешняя инструкция INSERT сделала значительное изменение.Query notifications treat the statement as a single entity, and the type of any message that is created will be the type of the nested DML, even if the significant change is from the outer INSERT statement itself.

  • В предложении <dml_table_source> предложения SELECT и WHERE не должны содержать вложенных запросов, агрегатных функций, ранжирующих функций, полнотекстовых предикатов, определяемых пользователем функций, осуществляющих доступ к данным, или функции TEXTPTR.In the <dml_table_source> clause, the SELECT and WHERE clauses cannot include subqueries, aggregate functions, ranking functions, full-text predicates, user-defined functions that perform data access, or the TEXTPTR function.

ParallelismParallelism

Предложение OUTPUT, возвращающее результаты клиенту, всегда использует последовательный план.An OUTPUT clause that returns results to the client will always use a serial plan.

Если в контексте базы данных с уровнем совместимости 130 или более высоким операция INSERT...SELECT использует указание WITH (TABLOCK) для инструкции SELECT, а также использует OUTPUT…INTO для вставки данных во временную или пользовательскую таблицу, конечная таблица для операции INSERT…SELECT допускает параллелизм в зависимости от стоимости поддерева.In the context of a database set to compatibility level 130 or higher, if an INSERT...SELECT operation uses a WITH (TABLOCK) hint for the SELECT statement and also uses OUTPUT...INTO to insert into a temporary or user table, then the target table for the INSERT...SELECT will be eligible for parallelism depending on the subtree cost. Конечная таблица, указанная в предложении OUTPUT INTO, не допускает параллелизма.The target table referenced in the OUTPUT INTO clause will not be eligible for parallelism.

ТриггерыTriggers

Возвращаемые из OUTPUT столбцы отражают данные после завершения выполнения инструкции INSERT, UPDATE или DELETE, но до выполнения триггеров.Columns returned from OUTPUT reflect the data as it is after the INSERT, UPDATE, or DELETE statement has completed but before triggers are executed.

Для триггеров INSTEAD OF возвращенные результаты формируются таким образом, как если бы операции INSERT, UPDATE или DELETE были действительно выполнены, даже если в результате выполнения триггера никакие реальные изменения данных не произведены.For INSTEAD OF triggers, the returned results are generated as if the INSERT, UPDATE, or DELETE had actually occurred, even if no modifications take place as the result of the trigger operation. Если инструкция, включающая предложение OUTPUT, указывается в тексте триггера, то вставленные и удаленные таблицы триггера должны адресоваться по псевдонимам, чтобы избежать появления повторяющихся ссылок на столбцы в таблицах INSERTED и DELETED, относящихся к предложению OUTPUT.If a statement that includes an OUTPUT clause is used inside the body of a trigger, table aliases must be used to reference the trigger inserted and deleted tables to avoid duplicating column references with the INSERTED and DELETED tables associated with OUTPUT.

Если предложение OUTPUT определено без указания ключевого слова INTO, для целевого объекта операции DML не могут быть определены триггеры, выполняемые для этой операции.If the OUTPUT clause is specified without also specifying the INTO keyword, the target of the DML operation cannot have any enabled trigger defined on it for the given DML action. Например, если предложение OUTPUT определено в инструкции UPDATE, целевая таблица не может иметь какие-либо включенные триггеры UPDATE.For example, if the OUTPUT clause is defined in an UPDATE statement, the target table cannot have any enabled UPDATE triggers.

Если установлен параметр disallow results from triggers процедуры sp_configure, инструкция с предложением OUTPUT без INTO при вызове из триггера приводит к ошибке.If the sp_configure option disallow results from triggers is set, an OUTPUT clause without an INTO clause causes the statement to fail when it is invoked from within a trigger.

Типы данныхData Types

Предложение OUTPUT поддерживает типы данных больших объектов: nvarchar(max) , varchar(max) , varbinary(max) , text, ntext, image и xml.The OUTPUT clause supports the large object data types: nvarchar(max), varchar(max), varbinary(max), text, ntext, image, and xml. Если в инструкции UPDATE указано предложение .WRITE для изменения столбца nvarchar(max) , varchar(max) или varbinary(max) , то возвращаются полные образы значений до и после изменения, если на них есть ссылки.When you use the .WRITE clause in the UPDATE statement to modify an nvarchar(max), varchar(max), or varbinary(max) column, the full before and after images of the values are returned if they are referenced. Функция TEXTPTR( ) не может входить в выражение, определенное в предложении OUTPUT для столбца, имеющего тип text, ntext или image.The TEXTPTR( ) function cannot appear as part of an expression on a text, ntext, or image column in the OUTPUT clause.

Очереди;Queues

Предложение OUTPUT может применяться в приложениях, которые применяют таблицы в качестве очередей или для хранения промежуточных результирующих наборов,You can use OUTPUT in applications that use tables as queues, or to hold intermediate result sets. то есть в приложениях, которые постоянно добавляют и удаляют строки из таблиц.That is, the application is constantly adding or removing rows from the table. В следующем примере предложение OUTPUT указано в инструкции DELETE и возвращает удаленную строку вызывающему приложению.The following example uses the OUTPUT clause in a DELETE statement to return the deleted row to the calling application.

USE AdventureWorks2012;  
GO  
DELETE TOP(1) dbo.DatabaseLog WITH (READPAST)  
OUTPUT deleted.*  
WHERE DatabaseLogID = 7;  
GO  
  

В этом примере строка удаляется из таблицы, используемой в качестве очереди, и удаляемое значение возвращается приложению.This example removes a row from a table used as a queue and returns the deleted values to the processing application in a single action. Можно реализовать также и другую семантику, например применение таблицы как стека.Other semantics may also be implemented, such as using a table to implement a stack. Однако при этом SQL ServerSQL Server не гарантирует порядок, в котором строки обрабатываются и возвращаются инструкциями DML с предложением OUTPUT.However, SQL ServerSQL Server does not guarantee the order in which rows are processed and returned by DML statements using the OUTPUT clause. Приложение должно указать соответствующее предложение WHERE, гарантирующее желаемую семантику, либо ориентироваться на то, что порядок, в котором строки обрабатываются операцией DML, не гарантируется.It is up to the application to include an appropriate WHERE clause that can guarantee the desired semantics, or understand that when multiple rows may qualify for the DML operation, there is no guaranteed order. В следующем примере для реализации порядка обработки строк применяется вложенный запрос, который предполагает уникальность значений в столбце DatabaseLogID.The following example uses a subquery and assumes uniqueness is a characteristic of the DatabaseLogID column in order to implement the desired ordering semantics.

USE tempdb;  
GO  
CREATE TABLE dbo.table1  
(  
    id INT,  
    employee VARCHAR(32)  
);  
GO  
  
INSERT INTO dbo.table1 VALUES   
      (1, 'Fred')  
     ,(2, 'Tom')  
     ,(3, 'Sally')  
     ,(4, 'Alice');  
GO  
  
DECLARE @MyTableVar TABLE  
(  
    id INT,  
    employee VARCHAR(32)  
);  
  
PRINT 'table1, before delete'   
SELECT * FROM dbo.table1;  
  
DELETE FROM dbo.table1  
OUTPUT DELETED.* INTO @MyTableVar  
WHERE id = 4 OR id = 2;  
  
PRINT 'table1, after delete'  
SELECT * FROM dbo.table1;  
  
PRINT '@MyTableVar, after delete'  
SELECT * FROM @MyTableVar;  
  
DROP TABLE dbo.table1;  
  
--Results  
--table1, before delete  
--id          employee  
------------- ------------------------------  
--1           Fred  
--2           Tom  
--3           Sally  
--4           Alice  
--  
--table1, after delete  
--id          employee  
------------- ------------------------------  
--1           Fred  
--3           Sally  
--@MyTableVar, after delete  
--id          employee  
------------- ------------------------------  
--2           Tom  
--4           Alice  
  

Примечание

Если сценарий позволяет нескольким приложениям производить разрушающее чтение из одной таблицы, в инструкциях UPDATE и DELETE следует указывать табличную подсказку READPAST.Use the READPAST table hint in UPDATE and DELETE statements if your scenario allows for multiple applications to perform a destructive read from one table. Это предотвратит блокировку, которая может возникнуть, если другое приложение уже считывает из таблицы первую подходящую запись.This prevents locking issues that can come up if another application is already reading the first qualifying record in the table.

РазрешенияPermissions

Необходимы разрешения SELECT на все столбцы, полученные через <dml_select_list> или указанные в <scalar_expression>.SELECT permissions are required on any columns retrieved through <dml_select_list> or used in <scalar_expression>.

Разрешения INSERT необходимы для всех таблиц, указанных в <output_table>.INSERT permissions are required on any tables specified in <output_table>.

ПримерыExamples

A.A. Применение предложения OUTPUT INTO в простой инструкции INSERTUsing OUTPUT INTO with a simple INSERT statement

В приведенном ниже примере производится вставка строки в таблицу ScrapReason, а затем с помощью предложения OUTPUT результаты выполнения инструкции возвращаются в переменную @MyTableVar``table.The following example inserts a row into the ScrapReason table and uses the OUTPUT clause to return the results of the statement to the @MyTableVar``table variable. Поскольку столбец ScrapReasonID определен со свойством IDENTITY, для него значение в инструкции INSERT не указывается.Because the ScrapReasonID column is defined with an IDENTITY property, a value is not specified in the INSERT statement for that column. Обратите внимание, что значение, которое компонент Компонент Database EngineDatabase Engine сформировал для этого столбца, возвращается предложением OUTPUT в столбец inserted.ScrapReasonID.However, note that the value generated by the Компонент Database EngineDatabase Engine for that column is returned in the OUTPUT clause in the column inserted.ScrapReasonID.

USE AdventureWorks2012;  
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 в инструкции DELETEUsing OUTPUT with a DELETE statement

В следующем примере производится удаление всех строк из таблицы ShoppingCartItem.The following example deletes all rows in the ShoppingCartItem table. Предложение OUTPUT deleted.* указывает, что результаты выполнения инструкции DELETE, то есть все столбцы удаляемых строк, будут возвращены вызывающему приложению.The clause OUTPUT deleted.* specifies that the results of the DELETE statement, that is all columns in the deleted rows, be returned to the calling application. Следующая инструкция SELECT проверяет результаты операции удаления из таблицы ShoppingCartItem.The SELECT statement that follows verifies the results of the delete operation on the ShoppingCartItem table.

USE AdventureWorks2012;  
GO  
DELETE Sales.ShoppingCartItem  
OUTPUT DELETED.*   
WHERE ShoppingCartID = 20621;  
  
--Verify the rows in the table matching the WHERE clause have been deleted.  
SELECT COUNT(*) AS [Rows in Table] FROM Sales.ShoppingCartItem WHERE ShoppingCartID = 20621;  
GO  
  

В.C. Применение предложения OUTPUT INTO в инструкции UPDATEUsing OUTPUT INTO with an UPDATE statement

В следующем примере в столбце VacationHours для первых 10 строк таблицы Employee устанавливается значение 25 %.The following example updates the VacationHours column in the Employee table by 25 percent for the first 10 rows. Предложение OUTPUT возвращает значение VacationHours, существующее до применения инструкции UPDATE в столбце deleted.VacationHours, и обновленное значение в столбце inserted.VacationHours к табличной переменной @MyTableVar.The OUTPUT clause returns the VacationHours value that exists before applying the UPDATE statement in the column deleted.VacationHours, and the updated value in the column inserted.VacationHours to the @MyTableVar table variable.

Две следующие инструкции SELECT возвращают значения в табличную переменную @MyTableVar, а результаты операции обновления — в таблицу Employee.Two SELECT statements follow that return the values in @MyTableVar and the results of the update operation in the Employee table.

USE AdventureWorks2012;  
GO  
  
DECLARE @MyTableVar table(  
    EmpID int NOT NULL,  
    OldVacationHours int,  
    NewVacationHours int,  
    ModifiedDate datetime);  
  
UPDATE TOP (10) HumanResources.Employee  
SET VacationHours = VacationHours * 1.25,  
    ModifiedDate = GETDATE()   
OUTPUT inserted.BusinessEntityID,  
       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.  
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate  
FROM HumanResources.Employee;  
GO  
  

Г.D. Применение предложения OUTPUT INTO для возврата выраженияUsing OUTPUT INTO to return an expression

Следующий пример, основанный на предыдущем примере, определяет выражение в предложении OUTPUT как разницу между обновленным значением VacationHours и значением VacationHours до применения операции обновления.The following example builds on example C by defining an expression in the OUTPUT clause as the difference between the updated VacationHours value and the VacationHours value before the update was applied. Значение этого выражения возвращается в переменную @MyTableVar``table в столбце VacationHoursDifference.The value of this expression is returned to the @MyTableVar``table variable in the column VacationHoursDifference.

USE AdventureWorks2012;  
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,  
    ModifiedDate = GETDATE()  
OUTPUT inserted.BusinessEntityID,  
       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) BusinessEntityID, VacationHours, ModifiedDate  
FROM HumanResources.Employee;  
GO  
  

Д.E. Применение предложения OUTPUT INTO с from_table_name в инструкции UPDATEUsing OUTPUT INTO with from_table_name in an UPDATE statement

В приведенном ниже примере производится обновление столбца ScrapReasonID таблицы WorkOrder для всех заказов на производство с указанными значениями ProductID и ScrapReasonID.The following example updates the ScrapReasonID column in the WorkOrder table for all work orders with a specified ProductID and ScrapReasonID. Предложение OUTPUT INTO возвращает значения из обновляемой таблицы (WorkOrder), а также из таблицы Product.The OUTPUT INTO clause returns values from the table being updated (WorkOrder) and also from the Product table. Таблица Product в предложении FROM указывает, какие строки следует обновлять.The Product table is used in the FROM clause to specify the rows to update. Для таблицы WorkOrder определен триггер AFTER UPDATE, поэтому требуется ключевое слово INTO.Because the WorkOrder table has an AFTER UPDATE trigger defined on it, the INTO keyword is required.

USE AdventureWorks2012;  
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  
  

Е.F. Применение предложения OUTPUT INTO с from_table_name в инструкции DELETEUsing OUTPUT INTO with from_table_name in a DELETE statement

В следующем примере производится удаление строк из таблицы ProductProductPhoto на основе критерия поиска, определенного в предложении FROM инструкции DELETE.The following example deletes rows in the ProductProductPhoto table based on search criteria defined in the FROM clause of DELETE statement. Предложение OUTPUT возвращает столбцы из таблицы, из которой производится удаление (deleted.ProductID, deleted.ProductPhotoID) и столбцы из таблицы Product.The OUTPUT clause returns columns from the table being deleted (deleted.ProductID, deleted.ProductPhotoID) and columns from the Product table. Эта таблица, указанная в предложении FROM, определяет, какие строки следует удалять.This table is used in the FROM clause to specify the rows to delete.

USE AdventureWorks2012;  
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  
  

Ж.G. Применение предложения OUTPUT INTO с типом данных больших объектовUsing OUTPUT INTO with a large object data type

В следующем примере для обновления части значения в столбце DocumentSummary, имеющем тип nvarchar(max) в таблице Production.Document, используется предложение .WRITE.The following example updates a partial value in DocumentSummary, an nvarchar(max) column in the Production.Document table, by using the .WRITE clause. Слово components заменяется словом features, при этом указывается новое слово, начальное смещение слова, заменяемого в исходном тексте и число заменяемых символов (длина).The word components is replaced by the word features by specifying the replacement word, the beginning location (offset) of the word to be replaced in the existing data, and the number of characters to be replaced (length). В примере предложение OUTPUT возвращает образы столбца DocumentSummary до и после изменения в переменную @MyTableVar``table.The example uses the OUTPUT clause to return the before and after images of the DocumentSummary column to the @MyTableVar``table variable. Обратите внимание, что возвращаются полные образы столбца DocumentSummary до и после изменения.Note that the full before and after images of the DocumentSummary column are returned.

USE AdventureWorks2012;  
GO  
DECLARE @MyTableVar table (  
    SummaryBefore nvarchar(max),  
    SummaryAfter nvarchar(max));  
  
UPDATE Production.Document  
SET DocumentSummary .WRITE (N'features',28,10)  
OUTPUT deleted.DocumentSummary,   
       inserted.DocumentSummary   
    INTO @MyTableVar  
WHERE Title = N'Front Reflector Bracket Installation';  
  
SELECT SummaryBefore, SummaryAfter   
FROM @MyTableVar;  
GO  
  

З.H. Применение предложения OUTPUT в триггере INSTEAD OFUsing OUTPUT in an INSTEAD OF trigger

Следующий пример демонстрирует применение предложения OUTPUT в триггере для возвращения результатов выполнения триггера.The following example uses the OUTPUT clause in a trigger to return the results of the trigger operation. Первым делом создается представление для таблицы ScrapReason, затем для этого представления определяется триггер INSTEAD OF INSERT, позволяющий пользователю изменять в базовой таблице только столбец Name.First, a view is created on the ScrapReason table, and then an INSTEAD OF INSERT trigger is defined on the view that lets only the Name column of the base table to be modified by the user. Так как столбец ScrapReasonID базовой таблицы является столбцом IDENTITY, триггер не учитывает значение, предоставленное пользователем.Because the column ScrapReasonID is an IDENTITY column in the base table, the trigger ignores the user-supplied value. Это приводит к тому, что компонент Компонент Database EngineDatabase Engine автоматически формирует верное значение.This allows the Компонент Database EngineDatabase Engine to automatically generate the correct value. Указанное пользователем значение ModifiedDate также не учитывается, и вместо него подставляется текущая дата.Also, the value supplied by the user for ModifiedDate is ignored and is set to the current date. Предложение OUTPUT возвращает значения, реально вставленные в таблицу ScrapReason.The OUTPUT clause returns the values actually inserted into the ScrapReason table.

USE AdventureWorks2012;  
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  
  

Ниже приведен результирующий набор, полученный 12 апреля 2004 года ('2004-04-12').Here is the result set generated on April 12, 2004 ('2004-04-12'). Обратите внимание, что столбцы ScrapReasonIDActual и ModifiedDate отражают те значения, которые были получены в результате выполнения триггера, а не те, что были указаны в инструкции INSERT.Notice that the ScrapReasonIDActual and ModifiedDate columns reflect the values generated by the trigger operation instead of the values provided in the INSERT statement.

ScrapReasonID  Name             ModifiedDate  
-------------  ---------------- -----------------------  
17             My scrap reason  2004-04-12 16:23:33.050

И.I. Применение предложения OUTPUT INTO со столбцами идентификаторов и вычисляемыми столбцамиUsing OUTPUT INTO with identity and computed columns

В следующем примере создается таблица EmployeeSales, а затем в нее с помощью инструкции INSERT вставляется несколько строк, получаемых инструкцией SELECT из исходных таблиц.The following example creates the EmployeeSales table and then inserts several rows into it using an INSERT statement with a SELECT statement to retrieve data from source tables. Таблица EmployeeSales содержит столбец идентификаторов (EmployeeID) и вычисляемый столбец (ProjectedSales).The EmployeeSales table contains an identity column (EmployeeID) and a computed column (ProjectedSales).

USE AdventureWorks2012 ;  
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(  
  EmployeeID   int NOT NULL,  
  LastName     nvarchar(20) NOT NULL,  
  FirstName    nvarchar(20) NOT NULL,  
  CurrentSales money NOT NULL,  
  ProjectedSales 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 EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales  
FROM @MyTableVar;  
GO  
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales  
FROM dbo.EmployeeSales;  
GO  
  

К.J. Применение предложений OUTPUT и OUTPUT INTO в одной инструкцииUsing OUTPUT and OUTPUT INTO in a single statement

В следующем примере производится удаление строк из таблицы ProductProductPhoto на основе критерия поиска, определенного в предложении FROM инструкции DELETE.The following example deletes rows in the ProductProductPhoto table based on search criteria defined in the FROM clause of DELETE statement. Предложение OUTPUT INTO возвращает столбцы из удаляемой таблицы (deleted.ProductID, deleted.ProductPhotoID) и столбцы из таблицы Product в переменную @MyTableVar``table.The OUTPUT INTO clause returns columns from the table being deleted (deleted.ProductID, deleted.ProductPhotoID) and columns from the Product table to the @MyTableVar``table variable. Таблица Product в предложении FROM определяет, какие строки необходимо удалять.The Product table is used in the FROM clause to specify the rows to delete. Предложение OUTPUT возвращает вызывающему приложению столбцы deleted.ProductID, deleted.ProductPhotoID, а также дату и время удаления строки из таблицы ProductProductPhoto.The OUTPUT clause returns the deleted.ProductID, deleted.ProductPhotoID columns and the date and time the row was deleted from the ProductProductPhoto table to the calling application.

USE AdventureWorks2012;  
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  
  

Л.K. Вставка данных, возвращенных предложением OUTPUTInserting data returned from an OUTPUT clause

В следующем примере собираются данные, возвращаемые предложением OUTPUT инструкции MERGE, а затем эти данные вставляются в другую таблицу.The following example captures data returned from the OUTPUT clause of a MERGE statement, and inserts that data into another table. Инструкция MERGE ежедневно обновляет столбец Quantity таблицы ProductInventory в соответствии с заказами, обрабатываемыми в таблице SalesOrderDetail.The MERGE statement updates the Quantity column of the ProductInventory table daily, based on orders that are processed in the SalesOrderDetail table. Инструкция также удаляет строки с продуктами, запас которых сократился до 0 или ниже.It also deletes rows for products whose inventories drop to 0 or below. В примере собираются удаленные строки и вставляются в другую таблицу, ZeroInventory, в которой ведется учет закончившихся продуктов.The example captures the rows that are deleted and inserts them into another table, ZeroInventory, which tracks products with no inventory.

USE AdventureWorks2012;  
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;  
  

См. также:See Also

DELETE (Transact-SQL) DELETE (Transact-SQL)
INSERT (Transact-SQL) INSERT (Transact-SQL)
UPDATE (Transact-SQL) UPDATE (Transact-SQL)
table (Transact-SQL) table (Transact-SQL)
CREATE TRIGGER (Transact-SQL) CREATE TRIGGER (Transact-SQL)
sp_configure (Transact-SQL)sp_configure (Transact-SQL)