Смущает SCOPE_IDENTITY () и GO - PullRequest
0 голосов
/ 10 мая 2018

Меня немного смущает документация и поведение SCOPE_IDENTITY () в SQL Server.

Эта страница https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql?view=sql-server-2017 говорит об этом SCOPE_IDENTITY ():

Возвращает последнее значение идентификатора, вставленное в столбец идентификаторов в та же сфера Область действия - это модуль: хранимая процедура, триггер, функция или партия . Поэтому, если два утверждения находятся в одном хранимая процедура, функция или пакет, они находятся в одной области действия.

И это содержит этот пример

USE AdventureWorks2012;  
GO  
INSERT INTO Person.ContactType ([Name]) VALUES ('Assistant to the Manager');  
GO  
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  
GO  
SELECT @@IDENTITY AS [@@IDENTITY];  
GO  

Что возвращает

SCOPE_IDENTITY  
21  
@@IDENTITY  
21

Из документов я бы подумал, что результатом SCOPE_IDENTITY () будет NULL, потому что SELECT SCOPE_IDENTITY () AS [SCOPE_IDENTITY]; выполняется в другом пакете (потому что он идет после GO), чем команда INSERT ... Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Не используйте scope_indentity. SQL Server имеет гораздо лучший способ возврата значений из вставки, предложение OUTPUT.

DECLARE @ids TABLE (id INT);

INSERT INTO Person.ContactType ([Name])
    OUTPUT inserted.ID INTO @ids  -- I'm not sure what the identity is named
    VALUES ('Assistant to the Manager');

Это имеет несколько преимуществ:

  • Вы можете вернуть больше столбцов, чем просто id.
  • Вы можете вернуть идентификаторы из вставок, которые имеют более одной строки.
  • Вам вообще не нужно беспокоиться о области видимости.
0 голосов
/ 10 мая 2018

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

Но учтите, что если вы создаете внутреннюю партию, выполняя EXEC со строкой, то SCOPE_IDENTITY этой внутренней партии не зависит от вашей внешней партии SCOPE_IDENTITY


Этот скрипт выдает значение 2, а не 5:

create table T1 (ID int IDENTITY(2,1000) not null,Val char(1))
create table T2 (ID int IDENTITY(5,1000) not null, Val char(1))
go
insert into T1(Val) values ('a')
exec('insert into T2(Val) values (''b'')')
select SCOPE_IDENTITY()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...