12 марта 2012 г.

Применение OUTPUT в инструкциях DML

Анализируя базы данных, я часто вижу, что возможности предложения OUTPUT в инструкциях DML не используются, а реализуются с помощью дополнительных запросов и встроенных функций SQL Server'а. Такая реализация всегда стоит дополнительных ресурсов  и отрицательно влияет на производительность приложения в целом.

OUTPUT предоставляет возможность вывода вставленных/измененных/удаленных данных в инструкциях INSERT, UPDATE, MERGE, DELETE. Строку, обрабатываемую такими инструкциями, можно целиком или частично вставить в табличную переменную (Пример 1), другую таблицу (Пример 2), просто вернуть клиентскому приложению или параллельно выполнить и то, и другое (Пример 3).

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

use tempdb
go

--
-- Тестовая таблица
--
create table t1
(
    id int identity,
    col1 nvarchar(55) null
)
go

--
-- Пример 1: Возвращает идентификатор вставленной строки
--
insert into t1(col1)
output inserted.id
values('testdata 1')
go

--
-- Пример 2: Вставляет данные в таблицу t2
--
create table t2
(
    dml_time datetime not null,
    dml_statement sysname not null,
    id int null,
    col1 nvarchar(55) null
)
go

insert into t1(col1)
output getdate(),'insert',inserted.*
into t2
values('testdata 2')

select * from t2
go

--
-- Пример 3: Вставляет данные в табличную переменную
--
declare @t table(col1 nvarchar(55))

insert into t1(col1)
output inserted.col1 into @t
output inserted.id as NewRowID
values('testdata 3')

select * from @t
go

--
-- Пример 4: Протоколирует удаляемые строки в таблицу t2
--
delete t1
output getdate(),'delete',deleted.*
into t2
where id = 1

select * from t2
go

--
-- Пример 5: Определение последнего значения идентификатора
--
insert into t1(col1)
values('testdata 5')

declare @id int = scope_identity()

select @id as id
go
--
-- Удаляет тестовые таблицы
--
drop table t1, t2
go

4 комментария:

  1. Спасибо!
    Как то даже и не знал о такой возможности

    ОтветитьУдалить
  2. жаль что нельзя :
    declare @a table
    (
    id int identity(1,1) not null,
    name varchar(50) not null,
    primary key clustered(id)
    )
    declare @id int
    insert into @a
    set @id = output inserted.id
    values ('asdasd')

    или можно? )

    ОтветитьУдалить
  3. Данные OUTPUT можно вставлять только в таблицу или табличную переменную, смотрите Пример 3. Для определения последнего значения идентификатора используют функцию SCOPE_IDENTITY() смотрите Пример 5.

    ОтветитьУдалить