Лучший способ получить личность вставленной строки?

Каков наилучший способ получить IDENTITY вставленной строки?

Я знаю о @@IDENTITY и IDENT_CURRENT и SCOPE_IDENTITY, но не понимаю плюсы и минусы, связанные с каждым.

Может кто-нибудь объяснит различия и когда я буду использовать их?

Ответы

Ответ 1

Ответ 2

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

например (взято из следующей статьи MSDN)

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

Ответ 3

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

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

SCOPE_IDENTITY() решает эту проблему. Он возвращает идентификатор последней вещи, которую вы вставили в код SQL, который вы отправили в базу данных. Если триггеры идут и создают дополнительные строки, они не будут возвращать неправильное значение. Hooray

IDENT_CURRENT возвращает последний идентификатор, который был вставлен кем-либо. Если какое-либо другое приложение случайно введет другую строку в нерабочее время, вы получите идентификатор этой строки, а не ваш.

Если вы хотите играть в нее безопасно, всегда используйте SCOPE_IDENTITY(). Если вы придерживаетесь @@IDENTITY, и кто-то решает добавить триггер позже, весь ваш код сломается.

Ответ 4

Самый лучший (читаемый: самый безопасный) способ получить личность вновь вставленной строки - это использовать предложение output:

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

Ответ 5

Добавить

SELECT CAST(scope_identity() AS int);

до конца вашего встраиваемого sql-оператора, затем

NewId = command.ExecuteScalar()

получит его.

Ответ 6

Когда вы используете Entity Framework, он внутренне использует метод OUTPUT для возврата вновь вставленного значения идентификатора

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g 
   JOIN dbo.TurboEncabulators AS t 
   ON g.Id = t.TurboEncabulatorID 
WHERE @@ROWCOUNT > 0

Результаты вывода сохраняются во временной переменной таблицы, соединенной назад с таблицей и возвращают значение строки из таблицы.

Примечание. Я понятия не имею, почему EF будет внутренне присоединяться к эфемерной таблице обратно к реальной таблице (при каких обстоятельствах они не совпадают).

Но это то, что делает EF.

Этот метод (OUTPUT) доступен только на SQL Server 2008 или новее.

Ответ 7

MSDN

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

@@IDENTITY и SCOPE_IDENTITY вернут последнее значение идентификации, сгенерированное в любой таблице текущего сеанса. Однако SCOPE_IDENTITY возвращает значение только в пределах текущей области; @@IDENTITY не ограничивается определенной областью.

IDENT_CURRENT не ограничивается областью и сеансом; он ограничен указанной таблицей. IDENT_CURRENT возвращает значение идентификатора, сгенерированное для конкретной таблицы, в любом сеансе и в любой области. Для получения дополнительной информации см. IDENT_CURRENT.

  • IDENT_CURRENT - это функция, которая принимает таблицу в качестве аргумента.
  • @@IDENTITY может возвращать запутанный результат, когда у вас есть триггер в таблице
  • SCOPE_IDENTITY - ваш герой большую часть времени.

Ответ 8

@@IDENTITY - это последняя идентификация, вставленная с использованием текущего соединения SQL. Это хорошее значение для возврата из хранимой процедуры вставки, где вам просто нужна идентификация, вставленная для вашей новой записи, и не волнует, что после этого добавлено больше строк.

SCOPE_IDENTITY - это последняя идентификация, вставленная с использованием текущего SQL-соединения, и в текущей области - то есть, если вторая вставка была вставлена ​​на основе триггера после вашей вставки, будет отображаться в SCOPE_IDENTITY, только вставку, которую вы выполнили. Честно говоря, у меня никогда не было причины использовать это.

IDENT_CURRENT (имя_таблицы) - это последняя идентификация, вставленная независимо от соединения или области видимости. Вы можете использовать это, если хотите получить текущее значение IDENTITY для таблицы, в которую вы не ввели запись.

Ответ 9

Я не могу говорить с другими версиями SQL Server, но в 2012 году вывод напрямую работает просто отлично. Вам не нужно беспокоиться о временной таблице.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

Кстати, этот метод также работает при вставке нескольких строк.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

Выход

ID
2
3
4

Ответ 10

ВСЕГДА используйте scope_identity(), НИКОГДА ничего не нужно.

Ответ 11

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

Ответ 12

После вашего заявления о вставки вам нужно добавить это. И Удостоверьтесь в имени таблицы, где данные вставляются. Вы получите текущую строку, где строка, затронутая только теперь вашим оператором insert.

IDENT_CURRENT('tableName')

Ответ 13

TL & DR: Создайте выходную переменную для размещения запроса на возвращение идентификатора. Это использовалось в Dotnet Core с PostGres. Я чувствую, что это может быть полезно для тех, кто не использует SQL.

Обоснование: оператор INSERT возвращает идентификатор, который можно получить только с помощью параметра OUTPUT. Смотрите ниже.

Цель состоит в том, чтобы получить ВЫХОД из "возвращающегося"

  NpgsqlParameter idOut = new NpgsqlParameter
        {
            Direction = System.Data.ParameterDirection.Output
        };
  await _context.Database.ExecuteSqlCommandAsync($"INSERT INTO pulserelations (pulseid, create_time, modified_time) VALUES ({pulse_id}, now(),now()) RETURNING pulserelationid;", idOut);

Ответ 14

Если вы ищете последний добавленный/обновленный идентификатор, это может быть немного старомодно, но есть много людей, использующих более старый PHP, Pre 5.5, если быть более точным. Более подробную информацию можно найти на http://php.net/manual/en/function.mysql-insert-id.php

$last = mysql_insert_id();