SQL Server 2005 a 2008 umožňují prostřednictvím klauzule OUTPUT u příkazů INSERT, UPDATE a DELETE vrátit jaké záznamy byly vloženy nebo smazány. Příklad:
1
2
3
| INSERT INTO author(surname)
OUTPUT inserted.id_author
VALUES('myAuthor') |
nebo
1
2
3
4
5
6
| declare table @myTempTable(
tempValue int not null
)
INSERT INTO author(surname)
OUTPUT inserted.id_author into @myTempTable(tempValue)
VALUES('myAuthor') |
V prvním případě se vrátí hodnota id_author, která vznikne po vložení záznamu do tabulky(např. prostřednictvím DEFAULTu). Tato hodnota se vrátí jako resultset.
V druhém případě se provede jen INSERT s tím, že vložená data se vrátí do dočasné tabulky, kterou je ovšem potřeba ještě předtím nadefinovat.
Pomocí tohoto postupu lze vrátit hodnota DEFAULT na kterou je navázána funkce newsequentialid(). Tato funkce vrací binárně seřazená data narozdíl od newid(), je tedy vhodnější pro sloupce na kterých má být clusterovaný index. Nevýhodou uniqueidentifieru je to, že narozdíl od IDENTITY se k nově vytvořené hodnotě nedá přistoupit přes funkci scope_identity() popř. @@identity. Takže i z tohoto důvodu byla přidána možnost OUTPUT klauzule.
OUTPUT se liší tím, že ovlivňované hodnoty se vypisují až za ni. Viz VALUES v horním příkladech. Za OUTPUT následuje inserted.* nebo inserted.sloupec a nebo deleted.* nebo deleted.sloupec
Tak a teď co je Composable DML?
Je to novinka v SQL Serveru 2008.
Spočívá v tom, že vytvořením resultsetu přes klauzuli OUTPUT je možné s těmito daty dále pracovat jako s derivovanou tabulkou pro kterou se definuje název výstupních sloupců.
Příklad:
1
2
3
4
5
| INSERT INTO books(id_author, pages) --vnější insert do tabulky knihy
SELECT id_author, 200 AS pages
FROM (INSERT INTO author(surname) --vnitřní insert do tabulky autoři
OUTPUT inserted.id_author
VALUES('myAuthor')) AS T(id_author); |
je to daleko krásnější řešení jako:
1
2
3
4
5
6
7
8
9
10
11
| declare @myTempVariable table(
tempValue uniqueidentifier not null
)
insert into author(surname)
output inserted.id_author into @myTempVariable(tempValue)
values('myAuthor')
insert into books(id_author, pages)
select tempValue, 120
from @myTempVariable |
Více je v tomto článku http://www.sqlmag.com/Article/ArticleID/99242/sql_server_99242.html
Omezení composable DML: Nelze ovlivňovat hodnoty, které jsou vkládány jako cizí klíč! V tomto případě tedy v tabulce books nesmí být id_author cizím klíčem.
O composable DML mi napsal pan Plamen Ratchev v rámci odpovědi na dotaz v diskusi Microsoft.public.sqlserver.programming. Velmi mu děkuji za cenné informace.