Dela via


OUTPUT-sats (Transact-SQL)

Gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-databas i Förhandsversion av Microsoft Fabric

Returnerar information från, eller uttryck baserat på, varje rad som påverkas av en INSERT, UPDATE, DELETEeller MERGE -instruktion. Dessa resultat kan returneras till bearbetningsprogrammet för användning i till exempel bekräftelsemeddelanden, arkivering och andra programkrav. Resultatet kan också infogas i en tabell- eller tabellvariabel. Dessutom kan du samla in resultatet av en OUTPUT sats i en kapslad INSERT, UPDATE, DELETE, eller MERGE -instruktion och infoga dessa resultat i en måltabell eller vy.

Note

En UPDATE- eller INSERTDELETE -instruktion som har en OUTPUT -sats returnerar rader till klienten även om -instruktionen stöter på fel och återställs. Resultatet ska inte användas om något fel inträffar när du kör -instruktionen.

Used in:

Transact-SQL syntaxkonventioner

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

Anger en tabellvariabel som de returnerade raderna infogas i i stället för att returneras till anroparen. @table_variable måste deklareras före instruktionen INSERT, UPDATE, DELETEeller MERGE .

Om column_list inte anges måste tabellvariabeln ha samma antal kolumner som resultatuppsättningenOUTPUT. Undantagen är identitets- och beräknade kolumner som måste hoppas över. Om column_list anges måste eventuella utelämnade kolumner antingen tillåta null-värden eller ha tilldelats standardvärden.

Mer information om tabellvariabler finns i tabellen.

output_table

Anger en tabell som de returnerade raderna infogas i i stället för att returneras till anroparen. output_table kan vara en tillfällig tabell.

Om column_list inte anges måste tabellen ha samma antal kolumner som resultatuppsättningen OUTPUT . Undantagen är identitets- och beräknade kolumner som måste hoppas över. Om column_list anges måste eventuella utelämnade kolumner antingen tillåta null-värden eller ha tilldelats standardvärden.

output_table can't:

  • Har aktiverat utlösare som definierats på den.
  • Delta på båda sidor av en FOREIGN KEY begränsning.
  • Ha CHECK begränsningar eller aktiverade regler.

column_list

En valfri lista med kolumnnamn i måltabellen för INTO -satsen. Det motsvarar den kolumnlista som tillåts i INSERT-instruktionen .

scalar_expression

Alla kombinationer av symboler och operatorer som utvärderas till ett enda värde. Mängdfunktioner tillåts inte i scalar_expression.

Alla referenser till kolumner i tabellen som ändras måste vara kvalificerade med prefixet INSERTED eller DELETED .

column_alias_identifier

Ett alternativt namn som används för att referera till kolumnnamnet.

DELETED

Ett kolumnprefix som anger det värde som tas bort av uppdaterings- eller borttagningsåtgärden och eventuella befintliga värden som inte ändras med den aktuella åtgärden. Kolumner som föregås av DELETED återspeglar värdet innan instruktionen UPDATE, DELETEeller MERGE har slutförts.

DELETED kan inte användas med OUTPUT -satsen i -instruktionen INSERT .

INSERTED

Ett kolumnprefix som anger det värde som läggs till av infognings- eller uppdateringsåtgärden och eventuella befintliga värden som inte ändras med den aktuella åtgärden. Kolumner som föregås av INSERTED återspeglar värdet efter att instruktionen UPDATE, INSERTeller MERGE har slutförts, men innan utlösare körs.

INSERTED kan inte användas med OUTPUT -satsen i -instruktionen DELETE .

from_table_name

Ett kolumnprefix som anger en tabell som ingår i -satsen i FROM en DELETE- eller UPDATEMERGE -instruktion som används för att ange de rader som ska uppdateras eller tas bort.

Om tabellen som ändras också anges i FROM -satsen måste alla referenser till kolumner i tabellen kvalificeras med prefixet INSERTED eller DELETED .

*

Asterisken (*) anger att alla kolumner som påverkas av åtgärden ta bort, infoga eller uppdatera returneras i den ordning de finns i tabellen.

I följande DELETE instruktion returneras till exempel OUTPUT DELETED.* alla kolumner som tagits bort från ShoppingCartItem tabellen:

DELETE Sales.ShoppingCartItem
    OUTPUT DELETED.*;

column_name

En explicit kolumnreferens. Alla referenser till den tabell som ändras måste vara korrekt kvalificerade av antingen INSERTED prefixet DELETED eller efter behov, till exempel: INSERTED.<column_name>.

$action

Endast tillgängligt för -instruktionen MERGE . Anger en kolumn av typen nvarchar(10) i instruktionen OUTPUT i en MERGE instruktion som returnerar ett av tre värden för varje rad: INSERT, UPDATEeller DELETE, enligt den åtgärd som utfördes på den raden.

Remarks

- OUTPUT <dml_select_list> satsen och OUTPUT <dml_select_list> INTO { @table_variable | output_table } -satsen kan definieras i en enda INSERT, UPDATE, DELETEeller MERGE -instruktion.

Note

Om inget annat anges refererar referenser till OUTPUT -satsen till både OUTPUT -satsen och OUTPUT INTO -satsen.

Satsen OUTPUT kan vara användbar för att hämta värdet för identitet eller beräknade kolumner efter en eller UPDATE åtgärdINSERT.

När en beräknad kolumn ingår i <dml_select_list>är motsvarande kolumn i utdatatabellen eller tabellvariabeln inte en beräknad kolumn. Värdena i den nya kolumnen är de värden som beräknades när instruktionen kördes.

Den ordning i vilken ändringarna tillämpas på tabellen och i vilken ordning raderna infogas i utdatatabellen eller tabellvariabeln är inte garanterade att motsvara.

Om parametrar eller variabler ändras som en del av en UPDATE -instruktion OUTPUT returnerar satsen alltid värdet för parametern eller variabeln som det var innan instruktionen kördes i stället för det ändrade värdet.

Du kan använda OUTPUT med en UPDATE eller DELETE -instruktion placerad på en markör som använder WHERE CURRENT OF syntax.

Satsen OUTPUT stöds inte i följande instruktioner:

  • DML-instruktioner som refererar till lokala partitionerade vyer, distribuerade partitionerade vyer eller fjärrtabeller.

  • INSERT -instruktioner som innehåller en EXECUTE -instruktion.

  • Fulltextpredikat tillåts inte i OUTPUT -satsen när databaskompatibilitetsnivån är inställd på 100.

  • Satsen OUTPUT INTO kan inte användas för att infoga i en vy eller raduppsättningsfunktion.

  • Det går inte att skapa en användardefinierad funktion om den innehåller en OUTPUT INTO sats som har en tabell som mål.

För att förhindra icke-terministiskt beteende OUTPUT kan satsen inte innehålla följande referenser:

  • Underfrågor eller användardefinierade funktioner som utför åtkomst till användar- eller systemdata eller antas utföra sådan åtkomst. Användardefinierade funktioner antas utföra dataåtkomst om de inte är schemabundna.

  • En kolumn från en vy eller infogad tabellvärdesfunktion när kolumnen definieras av någon av följande metoder:

    • A subquery.

    • En användardefinierad funktion som utför åtkomst till användar- eller systemdata, eller som antas utföra sådan åtkomst.

    • En beräknad kolumn som innehåller en användardefinierad funktion som utför användar- eller systemdataåtkomst i sin definition.

    När SQL Server identifierar en sådan kolumn i OUTPUT -satsen utlöses fel 4186.

Infoga data som returneras från en OUTPUT-sats i en tabell

När du samlar in resultatet av en OUTPUT sats i en kapslad INSERT, UPDATE, DELETE, eller MERGE -instruktion och infogar dessa resultat i en måltabell bör du ha följande information i åtanke:

  • Hela operationen är atomisk. Antingen både -instruktionen INSERT och den kapslade DML-instruktionen som innehåller instruktionen OUTPUT kör, eller så misslyckas hela -instruktionen.

  • Följande begränsningar gäller för målet för den yttre INSERT instruktionen:

    • Målet får inte vara en fjärrtabell, vy eller ett vanligt tabelluttryck.

    • Målet kan inte ha någon FOREIGN KEY begränsning eller refereras till av en FOREIGN KEY begränsning.

    • Utlösare kan inte definieras på målet.

    • Målet kan inte delta i sammanslagningsreplikering eller uppdateringsbara prenumerationer för transaktionsreplikering.

  • Följande begränsningar gäller för den kapslade DML-instruktionen:

    • Målet kan inte vara en fjärrtabell eller partitionerad vy.

    • Själva källan får inte innehålla en <dml_table_source> sats.

  • Satsen OUTPUT INTO stöds inte i INSERT instruktioner som innehåller en <dml_table_source> sats.

  • @@ROWCOUNT returnerar raderna som endast infogas av den yttre INSERT instruktionen.

  • @@IDENTITY, SCOPE_IDENTITYoch IDENT_CURRENT returnera identitetsvärden som endast genereras av den kapslade DML-instruktionen och inte värden som genereras av den yttre INSERT instruktionen.

  • Frågemeddelanden behandlar -instruktionen som en enda entitet, och den typ av meddelande som skapas är typen av kapslad DML, även om den betydande ändringen kommer från själva den yttre INSERT instruktionen.

  • <dml_table_source> I -satsen kan satserna SELECT och WHERE inte innehålla underfrågor, aggregeringsfunktioner, rangordningsfunktioner, fulltextpredikat, användardefinierade funktioner som utför dataåtkomst eller TEXTPTR() funktionen.

Parallelism

En OUTPUT sats som returnerar resultat till klienten, eller tabellvariabeln, använder alltid en serieplan.

I samband med en databas som är inställd på kompatibilitetsnivå 130 eller senare, om en INSERT...SELECT åtgärd använder ett WITH (TABLOCK) tips för -instruktionen SELECT och även använder OUTPUT...INTO för att infoga i en tillfällig tabell eller användartabell, är måltabellen INSERT...SELECT för den berättigad till parallellitet beroende på kostnaden för underträd. Måltabellen OUTPUT INTO som refereras i -satsen är inte berättigad till parallellitet.

Triggers

Kolumner som returneras från OUTPUT återspeglar data som de är efter att instruktionen , UPDATEeller -DELETEinstruktionen INSERThar slutförts, men innan utlösare körs.

För INSTEAD OF utlösare genereras de returnerade resultaten som om INSERT, UPDATEeller DELETE faktiskt hade inträffat, även om inga ändringar sker till följd av utlösaråtgärden. Om en instruktion som innehåller en OUTPUT sats används i en utlösartext, måste tabellalias användas för att referera till utlösaren som infogats och tagits bort för att undvika att duplicera kolumnreferenser med tabellerna INSERTED och DELETED som är associerade med OUTPUT.

OUTPUT Om satsen anges utan att även ange nyckelordet INTO kan målet för DML-åtgärden inte ha någon aktiverad utlösare definierad för den angivna DML-åtgärden. Om OUTPUT satsen till exempel definieras i en UPDATE -instruktion kan måltabellen inte ha några aktiverade UPDATE utlösare.

Om alternativet sp_configure inte tillåter resultat från utlösare anges gör en OUTPUT sats utan en INTO sats att instruktionen misslyckas när den anropas inifrån en utlösare.

Data types

OUTPUT Satsen stöder de stora objektdatatyperna: nvarchar(max), varchar(max), varbinary(max), text, ntext, image och xml. När du använder .WRITE -satsen i -instruktionen UPDATE för att ändra en nvarchar(max), varchar(max)eller varbinary(max) kolumn returneras hela före och efter bilder av värdena om de refereras. Funktionen TEXTPTR() kan inte visas som en del av ett uttryck i en text-, ntext- eller bildkolumn i OUTPUT -satsen.

Queues

Du kan använda OUTPUT i program som använder tabeller som köer eller för att lagra mellanliggande resultatuppsättningar. Programmet lägger alltså hela tiden till eller tar bort rader från tabellen. I följande exempel används OUTPUT -satsen i en DELETE -instruktion för att returnera den borttagna raden till det anropande programmet.

USE AdventureWorks2022;
GO

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

Det här exemplet tar bort en rad från en tabell som används som en kö och returnerar de borttagna värdena till bearbetningsprogrammet i en enda åtgärd. Andra semantik kan också implementeras, till exempel att använda en tabell för att implementera en stack. SQL Server garanterar dock inte i vilken ordning rader bearbetas och returneras av DML-instruktioner med hjälp av OUTPUT -satsen. Det är upp till programmet att inkludera en lämplig WHERE sats som kan garantera önskad semantik, eller förstå att det inte finns någon garanterad ordning när flera rader kan kvalificera sig för DML-åtgärden. I följande exempel används en underfråga och förutsätter att unikhet är en egenskap DatabaseLogID hos kolumnen för att implementera önskad ordningssemantik.

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;

Här är resultatet:

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

Note

Använd tabelltipset READPAST och UPDATEDELETE -instruktioner om ditt scenario tillåter att flera program utför en destruktiv läsning från en tabell. Detta förhindrar låsningsproblem som kan uppstått om ett annat program redan läser den första kvalificeringsposten i tabellen.

Permissions

SELECT behörigheter krävs för alla kolumner som hämtas via <dml_select_list> eller används i <scalar_expression>.

INSERT behörigheter krävs för alla tabeller som anges i <output_table>.

Examples

Kodexemplen i den här artikeln använder AdventureWorks2022- eller AdventureWorksDW2022-exempeldatabasen, som du kan ladda ned från startsidan Microsoft SQL Server Samples och Community Projects.

A. Använda OUTPUT INTO med en INSERT-instruktion

I följande exempel infogas en rad i ScrapReason tabellen och satsen används OUTPUT för att returnera resultatet av -instruktionen @MyTableVar till tabellvariabeln. ScrapReasonID Eftersom kolumnen definieras med en identitetsegenskap anges inget värde i instruktionen för den INSERT kolumnen. Värdet som genereras av databasmotorn för kolumnen returneras dock i OUTPUT -satsen i kolumnen INSERTED.ScrapReasonID.

USE AdventureWorks2022;
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. Använda OUTPUT med en DELETE-instruktion

I följande exempel tas alla rader i ShoppingCartItem tabellen bort. Satsen OUTPUT DELETED.* anger att resultatet av -instruktionen DELETE , dvs. alla kolumner i de borttagna raderna, returneras till det anropande programmet. Instruktionen SELECT som följer verifierar resultatet av borttagningsåtgärden i ShoppingCartItem tabellen.

USE AdventureWorks2022;
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. Använda OUTPUT INTO med en UPDATE-instruktion

I följande exempel uppdateras VacationHours kolumnen i Employee tabellen med 25 procent för de första 10 raderna. - OUTPUT satsen returnerar det VacationHours värde som finns innan instruktionen UPDATE tillämpas i kolumnen DELETED.VacationHoursoch det uppdaterade värdet i kolumnen INSERTED.VacationHours@MyTableVar tabellvariabeln.

Två SELECT instruktioner följer, som returnerar värdena i @MyTableVar och resultatet av uppdateringsåtgärden Employee i tabellen.

USE AdventureWorks2022;
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. Använda OUTPUT INTO för att returnera ett uttryck

Följande exempel bygger på exempel C genom att definiera ett uttryck i OUTPUT -satsen som skillnaden mellan det uppdaterade VacationHours värdet och VacationHours värdet innan uppdateringen tillämpades. Värdet för det här uttrycket returneras till @MyTableVar tabellvariabeln i kolumnen VacationHoursDifference.

USE AdventureWorks2022;
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. Använda OUTPUT INTO med from_table_name i en UPDATE-instruktion

I följande exempel uppdateras ScrapReasonID kolumnen i WorkOrder tabellen för alla arbetsorder med angivet ProductID och ScrapReasonID. Satsen OUTPUT INTO returnerar värden från tabellen som uppdateras (WorkOrder) och även från Product tabellen. Tabellen Product används i FROM -satsen för att ange de rader som ska uppdateras. Eftersom tabellen WorkOrder har en AFTER UPDATE definierad utlösare krävs nyckelordet INTO .

USE AdventureWorks2022;
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. Använda OUTPUT INTO med from_table_name i en DELETE-instruktion

I följande exempel tas rader i ProductProductPhoto tabellen bort baserat på sökvillkor som definierats i FROM instruktionssatsen DELETE . Satsen OUTPUT returnerar kolumner från tabellen som tas bort (DELETED.ProductID, DELETED.ProductPhotoID) och kolumner från Product tabellen. Den här tabellen används i FROM -satsen för att ange de rader som ska tas bort.

USE AdventureWorks2022;
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. Använda OUTPUT INTO med en stor objektdatatyp

I följande exempel uppdateras ett partiellt värde i DocumentSummary, en nvarchar(max) -kolumn i Production.Document tabellen med hjälp .WRITE av -satsen. Ordet components ersätts av ordet features genom att ange ersättningsordet, startplatsen (förskjutningen) för ordet som ska ersättas i befintliga data och antalet tecken som ska ersättas (längd). I exemplet används OUTPUT -satsen för att returnera före- och efterbilderna DocumentSummary av kolumnen till @MyTableVar tabellvariabeln. De fullständiga före- och efterbilderna av DocumentSummary kolumnen returneras.

USE AdventureWorks2022;
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. Använda OUTPUT i en i stället för en utlösare

I följande exempel används OUTPUT -satsen i en utlösare för att returnera resultatet av utlösaråtgärden. Först skapas en vy i ScrapReason tabellen och sedan definieras en INSTEAD OF INSERT utlösare i vyn som endast Name tillåter att kolumnen i bastabellen ändras av användaren. Eftersom kolumnen ScrapReasonID är en IDENTITY kolumn i bastabellen ignorerar utlösaren värdet som användaren har angett. Detta gör att databasmotorn automatiskt kan generera rätt värde. Dessutom ignoreras det värde som användaren anger för ModifiedDate och anges till aktuellt datum. - OUTPUT satsen returnerar de värden som faktiskt infogats ScrapReason i tabellen.

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

Här är resultatuppsättningen som genererades den 12 april 2004 ('2004-04-12'). Kolumnerna ScrapReasonIDActual och ModifiedDate återspeglar de värden som genereras av utlösaråtgärden i stället för de värden som anges i -instruktionen INSERT .

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

I. Använda OUTPUT INTO med identitets- och beräknade kolumner

I följande exempel skapas tabellen och flera rader infogas i den EmployeeSales med hjälp av en INSERT -instruktion med en SELECT -instruktion för att hämta data från källtabeller. Tabellen EmployeeSales innehåller en identitetskolumn (EmployeeID) och en beräknad kolumn (ProjectedSales).

USE AdventureWorks2022;
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.EmployeeID,
    INSERTED.LastName,
    INSERTED.FirstName,
    INSERTED.CurrentSales,
    INSERTED.ProjectedSales
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. Använda OUTPUT och OUTPUT INTO i en enda instruktion

I följande exempel tas rader i ProductProductPhoto tabellen bort baserat på sökvillkor som definierats i FROM instruktionssatsen DELETE . Satsen OUTPUT INTO returnerar kolumner från tabellen som tas bort (DELETED.ProductID, DELETED.ProductPhotoID) och kolumner från Product tabellen till @MyTableVar tabellvariabeln. Tabellen Product används i FROM -satsen för att ange de rader som ska tas bort. - OUTPUT satsen returnerar kolumnerna DELETED.ProductID, DELETED.ProductPhotoID och datum och tid då raden togs bort från ProductProductPhoto tabellen till det anropande programmet.

USE AdventureWorks2022;
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
INNER 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. Infoga data som returneras från en OUTPUT-sats

I följande exempel avbildas data som returneras från OUTPUT -satsen i en MERGE -instruktion och infogar dessa data i en annan tabell. Instruktionen MERGEQuantity uppdaterar kolumnen i ProductInventory tabellen dagligen, baserat på beställningar som bearbetas i SalesOrderDetail tabellen. Den tar också bort rader för produkter vars lager sjunker till 0 eller färre. Exemplet avbildar de rader som tas bort och infogar dem i en annan tabell, ZeroInventory, som spårar produkter utan inventering.

USE AdventureWorks2022;
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
        INNER 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;
GO