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

Изменения: 12 декабря 2006 г.

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

Применяется в следующих инструкциях.

DELETE

INSERT

UPDATE

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

Синтаксис

<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 }

Аргументы

  • @table_variable
    Указывает переменную типа table, в которую вставляются возвращаемые строки вместо возврата вызывающему приложению. Аргумент @table_variable должен быть объявлен ранее соответствующей инструкции INSERT, UPDATE или DELETE.

    Если не указан аргумент column_list, переменная типа table должна иметь то же число столбцов, что и результирующий набор OUTPUT, за исключением столбцов идентификаторов и вычисляемых столбцов, которые следует пропустить. Если аргумент column_list указан, то любые пропущенные столбцы должны либо допускать значение NULL, либо для них должны быть определены значения по умолчанию.

    Дополнительные сведения о переменных table см. в разделе table (Transact-SQL).

  • output_table
    Указывает таблицу, в которую вставляются возвращенные строки вместо передачи вызывающему приложению. Аргумент output_table может быть временной таблицей.

    Если аргумент column_list не указан, то таблица должна иметь то же число столбцов, что и результирующий набор OUTPUT, за исключением столбцов идентификаторов и вычисляемых столбцов. Эти столбцы следует пропустить. Если аргумент column_list указан, то любые пропущенные столбцы должны либо допускать значение NULL, либо для них должны быть определены значения по умолчанию.

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

    • Иметь включенные триггеры, определенные для нее.
    • Участвовать в ограничениях внешнего ключа с любой стороны.
    • Иметь ограничения CHECK или активированные правила.
  • column_list
    Необязательный список имен столбцов для целевой таблицы, указанной в предложении INTO. Он аналогичен списку столбцов, указываемому для инструкций INSERT.
  • scalar_expression
    Любое сочетание символов и операторов, результатом вычисления которого является единственное значение. Статистические функции в scalar_expression указывать нельзя.

    Ссылки на изменяемые столбцы таблицы должны предваряться префиксом INSERTED или DELETED.

  • column_alias_identifier
    Альтернативное имя, используемое для указания ссылок на этот столбец.
  • DELETED
    Префикс столбца, который указывает на значение, удаляемое в результате выполнения операции обновления или удаления. Столбцы, имеющие префикс DELETED, отражают значение, которое было до завершения выполнения инструкции UPDATE или DELETE.

    Префикс DELETED не может указываться вместе с предложением OUTPUT в инструкции INSERT.

  • INSERTED
    Префикс столбца, который указывает на значение, добавляемое в результате выполнении операции вставки или обновления. Столбцы, имеющие префикс INSERTED, отражают значение, полученное после завершения выполнения инструкции UPDATE или INSERT, но до выполнения триггеров.

    Префикс INSERTED не может указываться вместе с предложением OUTPUT в инструкции DELETE.

  • from_table_name
    Префикс столбца, который обозначает таблицу, содержащуюся в предложении FROM инструкции DELETE или UPDATE, и указывает обновляемые или удаляемые строки.

    Если изменяемая таблица указана также и в предложении FROM, все ссылки на столбцы, содержащиеся в этой таблице, должны предваряться префиксом INSERTED или DELETED.

  • *
    Указывает, что все столбцы, участвующие в операции удаления, вставки или обновления, возвращаются в том порядке, в котором они существуют в таблице.

    Например, в следующей инструкции DELETE предложение OUTPUT DELETED.* возвращает все столбцы, удаленные из таблицы ShoppingCartItem:

    DELETE Sales.ShoppingCartItem
        OUTPUT DELETED.*;
    
  • column_name
    Явное указание столбца. Любое указание столбцов в изменяемой таблице должно предваряться соответствующим префиксом INSERTED или DELETED, например: INSERTED**.**column_name.

Замечания

Предложения OUTPUT <dml_select_list> и OUTPUT <dml_select_list> INTO { @table_variable | output_table } могут быть указаны в инструкции INSERT, UPDATE или DELETE одновременно.

ms177564.note(ru-ru,SQL.90).gifПримечание.
Если не указано иное, ссылки на предложение OUTPUT относятся как к предложению OUTPUT, так и к предложению OUTPUT INTO.

Применение предложения OUTPUT может оказаться полезным при получении значения идентификаторов или вычисляемых столбцов после выполнения операций INSERT и UPDATE.

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

Предложение OUTPUT не поддерживается для:

  • Инструкций DML, которые содержат ссылки на локальные секционированные представления, распределенные секционированные представления или удаленные таблицы.
  • Инструкций INSERT, содержащих инструкции EXECUTE.

Предложение OUTPUT INTO не может быть использовано для вставки строк в представление или функцию, возвращающую набор строк.

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

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

Предложение OUTPUT можно указывать с инструкциями UPDATE и DELETE, применяемыми к курсору с использованием синтаксиса WHERE CURRENT OF.

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

Триггеры

Возвращаемые из OUTPUT столбцы отражают данные после завершения выполнения инструкции INSERT, UPDATE или DELETE, но до выполнения триггеров.

Для триггеров INSTEAD OF возвращенные результаты формируются таким образом, как если бы операции INSERT, UPDATE или DELETE были действительно выполнены, даже если в результате выполнения триггера никакие реальные изменения данных не произведены. Если инструкции, включающие предложение OUTPUT, указываются в теле триггера, то таблицы триггера inserted и deleted должны адресоваться по псевдонимам, чтобы избежать появления дубликатов ссылок на столбцы в таблицах INSERTED и DELETED, относящихся к предложению OUTPUT.

Если предложение OUTPUT определено без указания ключевого слова INTO, для целевого объекта операции DML не могут быть определены триггеры, выполняемые для этой операции. Например, если предложение OUTPUT определено в инструкции UPDATE, целевая таблица не может иметь какие-либо включенные триггеры UPDATE.

Если установлен параметр disallow results from triggers процедуры sp_configure, инструкция с предложением OUTPUT без INTO при вызове из триггера приводит к ошибке.

Типы данных

Предложение OUTPUT поддерживает типы данных больших объектов: nvarchar(max), varchar(max), varbinary(max), text, ntext, image и xml. Если в инструкции UPDATE указано предложение .WRITE для изменения столбца nvarchar(max), varchar(max) или varbinary(max), то возвращаются полные образы значений до и после изменения, если на них есть ссылки. Функция TEXTPTR( ) не может входить в выражение, определенное в предложении OUTPUT для столбца, имеющего тип text, ntext или image.

Очереди

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

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

В этом примере строка удаляется из таблицы, используемой в качестве очереди, и удаляемое значение возвращается приложению. Можно реализовать также и другую семантику, например применение таблицы как стека. Однако при этом SQL Server не гарантирует порядок, в котором строки обрабатываются и возвращаются инструкциями DML с предложением OUTPUT. Приложение должно указать соответствующее предложение WHERE, гарантирующее желаемую семантику, либо ориентироваться на то, что порядок, в котором строки обрабатываются операцией DML, не гарантируется. В следующем примере для реализации порядка обработки строк применяется вложенный запрос, который предполагает уникальность значений в столбце DatabaseLogID.

USE tempdb
go

CREATE TABLE table1
(
    id INT,
    employee VARCHAR(32)
)
go

INSERT INTO table1 VALUES(1, 'Fred')
INSERT INTO table1 VALUES(2, 'Tom')
INSERT INTO table1 VALUES(3, 'Sally')
INSERT INTO table1 VALUES(4, 'Alice')
GO

DECLARE @MyTableVar TABLE
(
    id INT,
    employee VARCHAR(32)
)

PRINT 'table1, before delete' 
SELECT * FROM table1

DELETE FROM table1
OUTPUT DELETED.* INTO @MyTableVar
WHERE id = 4 OR id = 2

PRINT 'table1, after delete'
SELECT * FROM table1

PRINT '@MyTableVar, after delete'
SELECT * FROM @MyTableVar

DROP TABLE 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
ms177564.note(ru-ru,SQL.90).gifПримечание.
Если сценарий позволяет нескольким приложениям производить разрушающее чтение из таблиц, в инструкциях UPDATE и DELETE следует указывать табличную подсказку READPAST. Это предотвратит блокировку, которая может возникнуть, если другое приложение уже считывает из таблицы первую подходящую запись.

Разрешения

Необходимы разрешения SELECT на все столбцы, полученные через <dml_select_list> или указанные в <scalar_expression>.

Разрешения INSERT необходимы на все таблицы, указанные в <output_table>.

Примеры

А. Применение предложения OUTPUT INTO в простой инструкции INSERT

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

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

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

Б. Применение предложения OUTPUT в инструкции DELETE

В следующем примере производится удаление всех строк из таблицы ShoppingCartItem. Предложение OUTPUT DELETED.* указывает, что результаты выполнения инструкции DELETE, то есть все столбцы удаляемых строк, будут возвращены вызывающему приложению. Следующая инструкция SELECT проверяет результаты операции удаления из таблицы ShoppingCartItem.

USE AdventureWorks;
GO
DELETE Sales.ShoppingCartItem
    OUTPUT DELETED.* ;

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

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

В следующем примере в столбце VacationHours для первых 10 строк таблицы Employee устанавливается значение 25%. Предложение OUTPUT возвращает значение VacationHours, которое было до применения инструкции UPDATE в столбце DELETED.VacationHours, и измененное значение столбца INSERTED.VacationHours в переменную @MyTableVar типа table.

Две следующие инструкции SELECT возвращают значения в табличную переменную @MyTableVar, а результаты операции обновления — в таблицу Employee. Обратите внимание, что результаты в столбце INSERTED.ModifiedDate не совпадают со значениями столбца ModifiedDate таблицы Employee. Это происходит из-за того, что имеется триггер AFTER UPDATE, меняющий значение ModifiedDate на текущую дату, который определен для таблицы Employee. Однако столбцы, возвращенные из OUTPUT, отражают данные, которые имели место до срабатывания триггеров.

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 
OUTPUT INSERTED.EmployeeID,
       DELETED.VacationHours,
       INSERTED.VacationHours,
       INSERTED.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
--Note that ModifiedDate reflects the value generated by an
--AFTER UPDATE trigger.
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

Г. Применение предложения OUTPUT INTO для возврата выражения

Следующий пример, основанный на предыдущем примере, определяет выражение в предложении OUTPUT как разницу между обновленным значением VacationHours и значением VacationHours до применения операции обновления. Значение этого выражения возвращается в переменной @MyTableVar типа table в столбце VacationHoursDifference.

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    VacationHoursDifference int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 
OUTPUT INSERTED.EmployeeID,
       DELETED.VacationHours,
       INSERTED.VacationHours,
       INSERTED.VacationHours - DELETED.VacationHours,
       INSERTED.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, 
    VacationHoursDifference, ModifiedDate
FROM @MyTableVar;
GO
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

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

В следующем примере производится обновление столбца ScrapReasonID таблицы WorkOrder для всех заказов на выполнение работ с указанными значениями ProductID и ScrapReasonID. Предложение OUTPUT INTO возвращает значения из обновляемой таблицы (WorkOrder), а также из таблицы Product. Таблица Product в предложении FROM указывает, какие строки следует обновлять. Поскольку для таблицы WorkOrder определен триггер AFTER UPDATE, ключевое слово INTO не требуется.

USE AdventureWorks;
GO
DECLARE @MyTestVar table (
    OldScrapReasonID int NOT NULL, 
    NewScrapReasonID int NOT NULL, 
    WorkOrderID int NOT NULL,
    ProductID int NOT NULL,
    ProductName nvarchar(50)NOT NULL);
UPDATE Production.WorkOrder
SET ScrapReasonID = 4
OUTPUT DELETED.ScrapReasonID,
       INSERTED.ScrapReasonID, 
       INSERTED.WorkOrderID,
       INSERTED.ProductID,
       p.Name
    INTO @MyTestVar
FROM Production.WorkOrder AS wo
    INNER JOIN Production.Product AS p 
    ON wo.ProductID = p.ProductID 
    AND wo.ScrapReasonID= 16
    AND p.ProductID = 733;
SELECT OldScrapReasonID, NewScrapReasonID, WorkOrderID, 
    ProductID, ProductName 
FROM @MyTestVar;
GO

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

В следующем примере производится удаление строк из таблицы ProductProductPhoto на основе критерия поиска, который задан в предложении FROM инструкции DELETE. Предложение OUTPUT возвращает столбцы из таблицы, из которой производится удаление (DELETED.ProductID, DELETED.ProductPhotoID) и столбцы из таблицы Product. Эта таблица, указанная в предложении FROM, определяет, какие строки следует удалять.

USE AdventureWorks
GO
DECLARE @MyTableVar table (
    ProductID int NOT NULL, 
    ProductName nvarchar(50)NOT NULL,
    ProductModelID int NOT NULL, 
    PhotoID int NOT NULL);

DELETE Production.ProductProductPhoto
OUTPUT DELETED.ProductID,
       p.Name,
       p.ProductModelID,
       DELETED.ProductPhotoID
    INTO @MyTableVar
FROM Production.ProductProductPhoto AS ph
JOIN Production.Product as p 
    ON ph.ProductID = p.ProductID 
    WHERE p.ProductModelID BETWEEN 120 and 130;

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

Ж. Применение предложения OUTPUT INTO с типом данных больших объектов

В следующем примере производится изменение части значения в столбце DocumentSummary, имеющем тип nvarchar(max), в таблице Production.Document, при использовании предложения .WRITE. Слово components заменяется словом features, при этом указывается новое слово, начальное смещение заменяемого слова в исходном тексте и число заменяемых символов (длина). В примере предложение OUTPUT возвращает образы столбца DocumentSummary до и после изменения в табличной переменной @MyTableVar типа table. Обратите внимание, что возвращаются полные образы столбца DocumentSummary до и после изменения.

USE AdventureWorks;
GO
DECLARE @MyTableVar table (
    DocumentID int NOT NULL,
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT INSERTED.DocumentID,
       DELETED.DocumentSummary, 
       INSERTED.DocumentSummary 
    INTO @MyTableVar
WHERE DocumentID = 3 ;
SELECT DocumentID, SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

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

Следующий пример демонстрирует применение предложения OUTPUT в триггере для возврата результатов выполнения триггера. Первым делом создается представление для таблицы ScrapReason, для этого представления определяется триггер INSTEAD OF INSERT, позволяющий пользователю изменять в базовой таблице только столбец Name. Так как столбец ScrapReasonID базовой таблицы является столбцом идентификаторов, триггер не учитывает значение, предоставленное пользователем. Это приводит к тому, что компонент Database Engine автоматически формирует верное значение. Указанное пользователем значение ModifiedDate также игнорируется, и вместо него подставляется текущая дата. Предложение OUTPUT возвращает значения, реально вставленные в таблицу ScrapReason.

USE AdventureWorks;
GO
IF OBJECT_ID('dbo.vw_ScrapReason','V') IS NOT NULL
    DROP VIEW dbo.vw_ScrapReason;
GO
CREATE VIEW dbo.vw_ScrapReason
AS (SELECT ScrapReasonID, Name, ModifiedDate
    FROM Production.ScrapReason);
GO
CREATE TRIGGER dbo.io_ScrapReason 
    ON dbo.vw_ScrapReason
INSTEAD OF INSERT
AS
BEGIN
--ScrapReasonID is not specified in the list of columns to be inserted 
--because it is an IDENTITY column.
    INSERT INTO Production.ScrapReason (Name, ModifiedDate)
        OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, 
               INSERTED.ModifiedDate
    SELECT Name, getdate()
    FROM inserted;
END
GO
INSERT vw_ScrapReason (ScrapReasonID, Name, ModifiedDate)
VALUES (99, N'My scrap reason','20030404');
GO

Ниже приведен результирующий набор, полученный 12 апреля 2004 года ('2004-04-12'). Обратите внимание, что столбцы ScrapReasonIDActual и ModifiedDate отражают те значения, которые были получены в результате выполнении триггера, а не те, что были указаны в инструкции INSERT.

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

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

В следующем примере создается таблица EmployeeSales, а затем в нее с помощью инструкции INSERT вставляется несколько строк, получаемых инструкцией SELECT из исходных таблиц. Таблица EmployeeSales содержит столбец идентификаторов (EmployeeID) и вычисляемый столбец (ProjectedSales). Поскольку эти значения создаются компонентом SQL Server Database Engine при вставке, ни один из этих столбцов нельзя задавать в переменной @MyTableVar.

USE AdventureWorks ;
GO
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
    DROP TABLE dbo.EmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( EmployeeID   int IDENTITY (1,5)NOT NULL,
  LastName     nvarchar(20) NOT NULL,
  FirstName    nvarchar(20) NOT NULL,
  CurrentSales money NOT NULL,
  ProjectedSales AS CurrentSales * 1.10 
);
GO
DECLARE @MyTableVar table(
  LastName     nvarchar(20) NOT NULL,
  FirstName    nvarchar(20) NOT NULL,
  CurrentSales money NOT NULL
  );

INSERT INTO dbo.EmployeeSales (LastName, FirstName, CurrentSales)
  OUTPUT INSERTED.LastName, 
         INSERTED.FirstName, 
         INSERTED.CurrentSales
  INTO @MyTableVar
    SELECT c.LastName, c.FirstName, sp.SalesYTD
    FROM HumanResources.Employee AS e
        INNER JOIN Sales.SalesPerson AS sp
        ON e.EmployeeID = sp.SalesPersonID 
        INNER JOIN Person.Contact AS c
        ON e.ContactID = c.ContactID
    WHERE e.EmployeeID LIKE '2%'
    ORDER BY c.LastName, c.FirstName;

SELECT LastName, FirstName, CurrentSales
FROM @MyTableVar;
GO
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
FROM dbo.EmployeeSales;
GO

К. Применение предложений OUTPUT и OUTPUT INTO в одной инструкции

В следующем примере производится удаление строк из таблицы ProductProductPhoto на основе критерия поиска, который задан в предложении FROM инструкции DELETE. Предложение OUTPUT INTO возвращает столбцы из таблицы, из которой производится удаление строк (DELETED.ProductID, DELETED.ProductPhotoID) и столбцы из таблицы Product в переменную @MyTableVar типа table. Таблица Product в предложении FROM определяет, какие строки необходимо удалять. Предложение OUTPUT возвращает вызывающему приложению столбцы DELETED.ProductID, DELETED.ProductPhotoID, а также дату и время удаления строки из таблицы ProductProductPhoto.

USE AdventureWorks
GO
DECLARE @MyTableVar table (
    ProductID int NOT NULL, 
    ProductName nvarchar(50)NOT NULL,
    ProductModelID int NOT NULL, 
    PhotoID int NOT NULL);
DELETE Production.ProductProductPhoto
OUTPUT DELETED.ProductID,
       p.Name,
       p.ProductModelID,
       DELETED.ProductPhotoID
    INTO @MyTableVar
OUTPUT DELETED.ProductID, DELETED.ProductPhotoID, GETDATE() AS DeletedDate 
FROM Production.ProductProductPhoto AS ph
JOIN Production.Product as p 
    ON ph.ProductID = p.ProductID 
WHERE p.ProductID BETWEEN 800 and 810;

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

См. также

Справочник

DELETE (Transact-SQL)
INSERT (Transact-SQL)
UPDATE (Transact-SQL)
table (Transact-SQL)
CREATE TRIGGER (Transact-SQL)
Хранимая процедура sp_configure (Transact-SQL)

Справка и поддержка

Получение помощи по SQL Server 2005

Журнал изменений

Версия Журнал

12 декабря 2006 г.

Измененное содержимое
  • Удалены неточные сведения об использовании вложенных запросов в scalar_expression. Чтобы избежать получения несогласованных результатов по строкам, больше не разрешаются вложенные запросы в предложении OUTPUT.