объем_идентичности против идентификатора_куррента - PullRequest
10 голосов
/ 20 февраля 2009

После долгих исследований меня немного смущает то, какой идентификационный трекер мне следует использовать в sql.

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

Таким образом, учитывая эту информацию, мне кажется, что наилучшая версия (если вы знаете, какую таблицу вы будете обновлять) - это identif_current. Тем не менее, после чтения кажется, что большинство людей предпочитают использовать scope_identity. В чем причина этого и есть ли недостатки в моей логике?

Ответы [ 6 ]

18 голосов
/ 20 февраля 2009

В этом случае вам нужно написать имя таблицы, что произойдет, если вы решите изменить имя таблицы? Тогда вы также не должны забывать обновить свой код, чтобы отразить это. Я всегда использую SCOPE_IDENTITY, если мне не нужен идентификатор из вставки, которая происходит в триггере, тогда я буду использовать @@ IDENTITY

Кроме того, большая разница в том, что IDENT_CURRENT даст вам идентификацию от другого процесса, который произвел вставку (другими словами, последнее сгенерированное значение идентификатора от любого пользователя) так что если вы делаете вставку, а затем кто-то делает вставку, прежде чем вы сделаете SELECT IDENT_CURRENT, вы получите значение личности этого другого человека

См. Также 6 различных способов получения текущего значения идентификатора , в котором есть некоторый код, объясняющий, что происходит, когда вы помещаете триггеры в таблицу

3 голосов
/ 26 июня 2009

Из того, что я прочитал: scope_identity () должен быть правильным ответом, однако похоже, что в SQL 2005 и SQL 2008 есть ошибка, которая может появиться, если ваша вставка приведет к параллельному результату. план запроса.

Посмотрите следующие статьи для получения более подробной информации:

@@IDENTITY vs SCOPE_IDENTITY() vs IDENT_CURRENT - Получить последний введенный идентификатор записи

Статья: Шесть причин, по которым вам стоит нервничать из-за параллелизма

См. Раздел под названием: 1. # 328811, «SCOPE_IDENTITY() иногда возвращает неверное значение»

0 голосов
/ 20 марта 2014

Теория гласит: Чтобы быть в курсе условий гонки и не заботиться о вставках внутри триггеров, вы должны использовать SCOPE_IDENTITY() НО ... в SCOPE_IDENTITY () есть @@ IDENTITY), как упомянуто и связано с другими пользователями. Вот обходные пути от Microsoft , которые учитывают эти ошибки.

Ниже самая актуальная часть из статьи. Он использует output предложение вставки:

DECLARE @MyNewIdentityValues table(myidvalues int)
declare @A table (ID int primary key)
insert into @A values (1)
declare @B table (ID int primary key identity(1,1), B int not null)
insert into @B values (1)
select
    [RowCount] = @@RowCount,
    [@@IDENTITY] = @@IDENTITY,
    [SCOPE_IDENTITY] = SCOPE_IDENTITY()

set statistics profile on
insert into _ddr_T
output inserted.ID into @MyNewIdentityValues
    select
            b.ID
        from @A a
            left join @B b on b.ID = 1
            left join @B b2 on b2.B = -1

            left join _ddr_T t on t.T = -1

        where not exists (select * from _ddr_T t2 where t2.ID = -1)
set statistics profile off

select
    [RowCount] = @@RowCount,
    [@@IDENTITY] = @@IDENTITY,
    [SCOPE_IDENTITY] = SCOPE_IDENTITY(),
    [IDENT_CURRENT] = IDENT_CURRENT('_ddr_T')
select * from @MyNewIdentityValues
go
0 голосов
/ 05 декабря 2012

SELECT IDENT_CURRENT - как вы сказали, вы получите конкретное последнее вставленное значение идентификатора таблицы. Есть проблемы, связанные с этим: один пользователь должен иметь разрешение на просмотр метаданных, в противном случае он возвращает NULL, а второй - жесткое кодирование имени таблицы, что приведет к проблеме в случае изменения имени таблицы.

Лучше всего использовать Scope_Identity вместе с переменной ... Смотрите следующий пример

 DECLARE @myFirstTableID INT

  DECLARE @mySecondTableID INT

  INSERT INTO MYFirstTable (....) VALUES (.....)

   SELECT @myFirstTableID =SCOPE_IDENTITY()


  INSERT INTO MYSecondTable () VALUES (.....)


   SELECT @mySecondTableID=SCOPE_IDENTITY()

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

0 голосов
/ 27 сентября 2011
/*
* IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
* @@IDENTITY returns the last identity value generated for any table in the current session, across all scopes.
* SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope.
*/

IF OBJECT_ID(N't6', N'U') IS NOT NULL
    DROP TABLE t6 ;
GO
IF OBJECT_ID(N't7', N'U') IS NOT NULL
    DROP TABLE t7 ;
GO
CREATE TABLE t6 (id INT IDENTITY) ;
CREATE TABLE t7
    (
     id INT IDENTITY(100, 1)
    ) ;
GO
CREATE TRIGGER t6ins ON t6
    FOR INSERT
AS
    BEGIN
        INSERT  t7
                DEFAULT VALUES
    END ;
GO
--End of trigger definition

SELECT  id
FROM    t6 ;
--IDs empty.

SELECT  id
FROM    t7 ;
--ID is empty.

--Do the following in Session 1
INSERT  t6
        DEFAULT VALUES ;
SELECT  @@IDENTITY ;
/*Returns the value 100. This was inserted by the trigger.*/

SELECT  SCOPE_IDENTITY() ;
/* Returns the value 1. This was inserted by the
INSERT statement two statements before this query.*/

SELECT  IDENT_CURRENT('t7') ;
/* Returns 100, the value inserted into t7, that is in the trigger.*/

SELECT  IDENT_CURRENT('t6') ;
/* Returns 1, the value inserted into t6 four statements before this query.*/

-- Do the following in Session 2.
SELECT  @@IDENTITY ;
/* Returns NULL because there has been no INSERT action
up to this point in this session.*/

SELECT  SCOPE_IDENTITY() ;
/* Returns NULL because there has been no INSERT action
up to this point in this scope in this session.*/

SELECT  IDENT_CURRENT('t7') ;
/* Returns 100, the last value inserted into t7.*/
0 голосов
/ 20 февраля 2009

См. этот блог для подробного ответа. Scope_identity никогда не будет возвращать идентификаторы из-за вставок, выполненных триггерами. Не было бы хорошей идеей использовать идент_куррент в мире перемен, где имена таблиц изменены .. как в dev env.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...