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

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

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

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

INSERT INTO Table1(fields...) OUTPUT INSERTED.id VALUES (...) или более старый метод: INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();, вы можете получить его в C# с помощью ExecuteScalar ().

S.Serpooshan 14.11.2016 11:11

Чем это лучше других ответов? (также - почему вы не публикуете это как ответ вместо комментария). Пожалуйста, напишите полный ответ (и объясните, почему это лучший вариант, чем опубликованные - если версия специфична, скажите так).

Oded 14.11.2016 15:25

это просто краткое изложение. ; D В принятом ответе не упоминается синтаксис предложения OUTPUT и отсутствует образец. Также образцы в других сообщениях не такие чистые ...

S.Serpooshan 14.11.2016 15:32

@saeedserpooshan - тогда отредактируйте это. Вы можете это сделать, понимаете? Видите, когда был опубликован этот ответ? Это предшествует предложению OUTPUT в SQL Server.

Oded 14.11.2016 15:37
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1 196
4
944 868
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Из MSDN

@@IDENTITY, SCOPE_IDENTITY, and IDENT_CURRENT are similar functions in that they return the last value inserted into the IDENTITY column of a table.

@@IDENTITY and SCOPE_IDENTITY will return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.

IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT.

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

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

  • IDENT_CURRENT('tableName') возвращает последнее значение идентификатора, созданное для конкретной таблицы в любом сеансе и любой области. Это позволяет вам указать, из какой таблицы вы хотите получить значение, на случай, если две приведенные выше не совсем то, что вам нужно (очень редкий). Кроме того, как упоминалось в @ Гай Старбак: «Вы можете использовать это, если хотите получить текущее значение IDENTITY для таблицы, в которую вы не вставляли запись».

  • Пункт OUTPUT оператора INSERT позволит вам получить доступ к каждой строке, которая была вставлена ​​с помощью этого оператора. Поскольку он привязан к конкретному оператору, он более простой, чем другие функции, указанные выше. Однако это небольшой более подробный (вам нужно вставить в таблицу переменную / временную таблицу, а затем запросить ее), и он дает результаты даже в сценарии ошибки, когда оператор откатывается. Тем не менее, если ваш запрос использует план параллельного выполнения, это только гарантированный метод для получения идентификатора (за исключением отключения параллелизма). Однако он выполняет триггеры перед и не может использоваться для возврата значений, созданных триггером.

известная ошибка с SCOPE_IDENTITY (), возвращающей неправильные значения: blog.sqlauthority.com/2009/03/24/… решение состоит в том, чтобы не запускать INSERT в многопроцессорном параллельном плане или использовать предложение OUTPUT

KM. 28.01.2010 17:59

@@ Identity хуже использовать Scope_identity. Практически никогда не следует использовать @@ identity.

HLGEM 20.05.2011 18:47

identity_current чрезвычайно опасен для целостности данных. Кто-то использовал это, и одновременные действия с базой данных привели к тому, что дочерние таблицы были назначены не тому человеку. Когда это происходит, исправить данные практически невозможно.

HLGEM 20.05.2011 18:49

Почти каждый раз, когда мне нужна была «идентичность», я хотел знать ключ (и) только что вставленной записи (ов). Если это ваша ситуация, вы хотите использовать предложение OUTPUT. Если вы хотите чего-то еще, приложите усилия, чтобы прочитать и понять ответ bdukes.

jerry 15.02.2012 19:48

Еще одна причина не использовать @@ Indentity заключается в том, что, по моему опыту, это O (n), а SCOPE_IDENTITY () - O (1). Он появился только на действительно большом столе.

paparazzo 01.10.2012 17:07

С output вам не нужно создавать временную таблицу для хранения и запроса результатов. Просто оставьте часть into в предложении вывода, и он выведет их в набор результатов.

spb 06.01.2014 23:04

Чтобы спасти других от паники, упомянутая выше ошибка была исправлена ​​в накопительном обновлении 5 для SQL Server 2008 R2 с пакетом обновления 1.

GaTechThomas 08.09.2014 21:09

Почему ограничение SCOPE_IDENTITY текущей областью действия не делает его безопасным в использовании?

Rob Grant 26.09.2014 10:47

Можем ли мы получить идентичность с помощью нескольких вставок?

Jeeva Jsb 28.09.2015 11:39

Обратите внимание, что кажется, что вы не можете использовать OUTPUT, когда две таблицы имеют отношение fkey, если вы не используете промежуточную временную таблицу (которая должна быть уже определена перед оператором INSERT).

Michael L. 30.08.2016 22:31

Предложение OUTPUT также содержит ошибки, поскольку не учитывает выполнение триггеров, а также имеет проблемы с отметками времени. Мне пришлось изменить возврат значений с OUTPUT обратно на SCOPE_IDENTITY в дополнительном SELECT именно для этой ошибки. См. Также: stackoverflow.com/a/13198916/2557263

Alejandro 14.05.2018 23:33

@niico, я думаю, что рекомендация такая же, как и раньше: OUTPUT - "лучший", если вы не используете триггеры и не обрабатываете ошибки, но SCOPE_IDENTITY - самый простой и очень редко вызывает проблемы.

bdukes 26.02.2019 22:07

Практически: сгенерируйте uuid и вставьте его. Тогда вы легко сможете определить свой ряд.

Frank Roth 13.03.2019 15:52

Обратите внимание, что ошибка SCOPE_IDENTITY была явно исправлена ​​давно в CU5 SQL Server 2008 R2: см. Здесь, support.microsoft.com/en-us/help/2019779/…

RBarryYoung 01.11.2020 15:57

Также обратите внимание, что большое преимущество OUTPUT перед другими методами состоит в том, что он может захватыватьнесколькосгенерированные значения идентичности при вставке нескольких строк.

RBarryYoung 01.11.2020 15:58

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

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

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

Никогда не используйте для этой цели @@ identity. Если позже кто-то добавит триггер, вы потеряете целостность данных. @@ identity - чрезвычайно опасная практика.

HLGEM 20.05.2011 18:51

"значение для таблицы, в которую вы <<не>> вставили запись." Действительно?

Abdul Saboor 26.02.2013 14:07

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

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

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

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

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

Что, если предположим, что 2 или 5 пользователей будут создавать запись одновременно, предоставит ли SCOPE_IDENTITY () нужную запись для каждого пользователя, или?

SlavaCa 13.11.2020 03:44

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

Не совсем никогда, но в 99 случаях из 100 вы будете использовать Scope_Identity ().

CJM 10.10.2009 00:44

Для чего вы еще что-нибудь использовали?

erikkallen 10.10.2009 01:31

если вы вставляете несколько строк с помощью INSERT-SELECT, вам нужно будет захватить несколько идентификаторов с помощью предложения OUTPUT

KM. 28.01.2010 17:48

@KM: Да, но я сослался на scope_identity vs @@ identity vs identify_current. OUTPUT - это совершенно другой класс, который часто бывает полезен.

erikkallen 29.01.2010 14:10

Ознакомьтесь с ответом Орри (stackoverflow.com/a/6073578/2440976) на этот вопрос - параллельно, и в качестве наилучшей практики было бы разумно следовать его настройке ... просто великолепно!

Dan B 02.09.2014 01:06

Почему это лучше, чем Output Inserted.Id?

niico 19.02.2019 18:08

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

например (взято из следующей статьи 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

Да, это правильный метод в будущем, используйте только один из других, если вы не используете SQL Server 2008 (мы пропустили 2005 год, поэтому не уверены, был ли тогда доступен OUTPUT)

HLGEM 20.05.2011 18:48

@HLGEM Есть Страница MSDN для OUTPUT в SQL Server 2005, так что похоже, что это просто SQL Server 2000 и более ранние версии, которые без него

bdukes 20.05.2011 19:14

Для действительно краткого примера, чтобы просто получить вставленный идентификатор, посмотрите: stackoverflow.com/a/10999467/2003325

Luke 29.07.2015 10:29

Использование INTO с OUTPUT - хорошая идея. См .: blogs.msdn.microsoft.com/sqlprogrammability/2008/07/11/… (Из комментария здесь: stackoverflow.com/questions/7917695/…)

shlgug 01.12.2016 20:22

Я только что узнал об этой функции OUTPUT INSERT, которая выглядит как настоящий ответ, очень хорошо работает в sqlserver, но не работает с классом SqlClient, она выдает исключение System.Data.SqlClient.SqlException: «Не удается найти ни столбец INSERTED», ни пользовательская функция или агрегат «INSERTED.Id», или имя неоднозначно. ', я поднимаю вопрос в другом потоке, поэтому, если кто-нибудь знает решение, буду признателен: stackoverflow.com/questions/49786640/…

Yogurtu 12.04.2018 04:31

Можно ли получить столбцы из части VALUES (или SELECT, если вы ее используете)? Примеры в MSDN показывают, что в операторе DELETE, но я не могу заставить его работать с SELECT / VALUES

Henrik Staun Poulsen 26.03.2019 12:19

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

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

-- type of this table's 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)

Кластеризация SQL-серверов - это функция высокой доступности, не имеющая отношения к параллелизму. В любом случае, очень редко для вставок одной строки (наиболее распространенный случай для scope_identity()) получаются параллельные планы. И эта ошибка была исправлена ​​более чем за год до этого ответа.

Martin Smith 07.01.2017 21:51

Что вы имеете в виду под параллелизмом?

user1451111 06.11.2017 11:47

@MartinSmith. Клиент не хотел допускать простоя на своем кластере серверов для установки CU, исправляющего эту проблему (не шутка), поэтому единственным решением для нас было переписать весь SQL, чтобы использовать output вместо scope_identity(). Я удалил FUD о кластеризации в ответе.

Ian Kemp 06.11.2017 15:26

Спасибо, это единственный пример, который мне удалось найти, который показывает, как использовать значение из вывода в переменной, а не просто выводить его.

Sean Ray 21.03.2018 17:50

Добавлять

SELECT CAST(scope_identity() AS int);

до конца вашей инструкции insert sql, затем

NewId = command.ExecuteScalar()

получит его.

Откуда у вас NewId? А какой у него заявленный тип? Чтобы хранить в нем command.ExecuteScalar(), я предполагаю, что это Object?

TylerH 11.09.2020 01:00

Когда вы используете 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 или новее.

Редактировать - Причина присоединения

Причина, по которой Entity Framework присоединяется к исходной таблице, а не просто использует значения OUTPUT, заключается в том, что EF также использует этот метод для получения rowversion вновь вставленной строки.

Вы можете использовать оптимистичный параллелизм в моделях инфраструктуры сущностей с помощью используя атрибут Timestamp: ?

public class TurboEncabulator
{
   public String StatorSlots)

   [Timestamp]
   public byte[] RowVersion { get; set; }
}

Когда вы это сделаете, Entity Framework потребуется rowversion только что вставленной строки:

DECLARE @generated_keys table([Id] uniqueidentifier)

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

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

И чтобы получить этот Timetsamp, вы не можешь используете предложение OUTPUT.

Это потому, что если в таблице есть триггер, любой Timestamp, который вы ВЫВОДИТЕ, будет неправильным:

  • Начальная вставка. Отметка времени: 1
  • Предложение OUTPUT выводит отметку времени: 1
  • триггер изменяет строку. Отметка времени: 2

Возвращенная временная метка будет правильной никогда, если у вас есть триггер в таблице. Итак, вы должен используете отдельный SELECT.

И даже если вы были готовы столкнуться с неправильной версией строки, другой причиной для выполнения отдельного SELECT является то, что вы не можете ВЫВОДИТЬ rowversion в табличную переменную:

DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)

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

Третья причина сделать это - симметрия. При выполнении UPDATE для таблицы с триггером вы не можешь используете предложение OUTPUT. Попытка сделать UPDATE с OUTPUT не поддерживается и выдаст ошибку:

Единственный способ сделать это - выполнить следующий запрос SELECT:

UPDATE TurboEncabulators
SET StatorSlots = 'Lotus-O deltoid type'
WHERE ((TurboEncabulatorID = 1) AND (RowVersion = 792))

SELECT RowVersion
FROM TurboEncabulators
WHERE @@ROWCOUNT > 0 AND TurboEncabulatorID = 1

Я предполагаю, что они соответствуют им, чтобы гарантировать целостность (например, в режиме оптимистичного параллелизма, когда вы выбираете переменную таблицы, кто-то мог удалить строки средства вставки). Также мне нравится ваш TurboEncabulators :)

zaitsman 23.11.2017 06:30

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

IDENT_CURRENT('tableName')

Вы заметили, что на это предложение уже несколько раз приходили ответы?

TT. 31.12.2017 10:53

да. но я пытаюсь описать решение по-своему.

Khan Ataur Rahman 31.12.2017 13:09

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

Trondster 09.03.2018 16:50

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

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

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

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

Выход

ID
2
3
4

Если вы хотите использовать его позже, я полагаю, вам понадобится временная таблица

IEnjoyEatingVegetables 05.11.2018 23:39

@JohnOsborne Вы можете использовать временную таблицу, если хотите, но я хочу сказать, что это не требование OUTPUT. Если вам не нужна временная таблица, тогда ваш запрос будет намного проще.

MarredCheese 06.11.2018 02:33

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

1) Создать строку

INSERT INTO table (uuid, name, street, zip) 
        VALUES ('2f802845-447b-4caa-8783-2086a0a8d437', 'Peter', 'Mainstreet 7', '88888');

2) Получить созданную строку

SELECT * FROM table WHERE uuid='2f802845-447b-4caa-8783-2086a0a8d437';

Не забудьте создать индекс для uuid в базе данных. Так строка будет найдена быстрее.

Frank Roth 24.12.2019 14:54

Для node.js вы можете использовать этот модуль, чтобы просто создать uuid: https://www.npmjs.com/package/uuid. const uuidv4 = require('uuid/v4'); const uuid = uuidv4()

Frank Roth 24.12.2019 15:00

GUID не является значением идентификатора, он имеет некоторые отступы по сравнению с простым целым числом.

Alejandro 26.03.2020 19:27

Кроме того, если UUID создается на уровне таблицы SQL как тип данных UNIQUEIDENTIFIER со значением по умолчанию newid(), вы не сможете получить его с помощью этого метода. Таким образом, вам нужно будет ВСТАВИТЬ, оставив поле UUID пустым, а затем выполнить OUTPUT INSERTED.uuid, чтобы получить его.

Keith E. Truesdell 18.06.2020 00:18

Еще один способ гарантировать идентичность вставляемых строк - указать значения идентичности и использовать SET IDENTITY_INSERT ON, а затем OFF. Это гарантирует, что вы точно знаете, каковы значения идентичности! Пока значения не используются, вы можете вставить эти значения в столбец идентификаторов.

CREATE TABLE #foo 
  ( 
     fooid   INT IDENTITY NOT NULL, 
     fooname VARCHAR(20) 
  ) 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

SET IDENTITY_INSERT #foo ON 

INSERT INTO #foo 
            (fooid, 
             fooname) 
VALUES      (1, 
             'one'), 
            (2, 
             'Two') 

SET IDENTITY_INSERT #foo OFF 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

INSERT INTO #foo 
            (fooname) 
VALUES      ('Three') 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

-- YOU CAN INSERT  
SET IDENTITY_INSERT #foo ON 

INSERT INTO #foo 
            (fooid, 
             fooname) 
VALUES      (10, 
             'Ten'), 
            (11, 
             'Eleven') 

SET IDENTITY_INSERT #foo OFF 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

SELECT * 
FROM   #foo 

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

Несмотря на то, что это более старый поток, есть новый способ сделать это, который позволяет избежать некоторых ошибок столбца IDENTITY в старых версиях SQL Server, вроде пробелов в значениях идентичности после перезагрузки сервера. Последовательности доступны в SQL Server 2016 и далее, что является более новым способом создания объекта SEQUENCE с использованием TSQL. Это позволяет вам создать собственный объект числовой последовательности в SQL Server и контролировать его приращение.

Вот пример:

CREATE SEQUENCE CountBy1  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  

Затем в TSQL вы должны сделать следующее, чтобы получить следующий идентификатор последовательности:

SELECT NEXT VALUE FOR CountBy1 AS SequenceID
GO

Вот ссылки на СОЗДАТЬ ПОСЛЕДОВАТЕЛЬНОСТЬ и СЛЕДУЮЩЕЕ ЗНАЧЕНИЕ ДЛЯ

Последовательности имеют те же проблемы идентичности, как пробелы (которые на самом деле не являются проблемами).

Alejandro 26.03.2020 19:29

Пробелы в идентификаторах возникали случайным образом при перезапуске SQL Server. Эти пробелы не возникают в новых приращениях ПОСЛЕДОВАТЕЛЬНОСТИ, если разработчик не использует генерируемую ПОСЛЕДОВАТЕЛЬНОСТЬ или откатывает транзакцию, которая должна была использовать следующий идентификатор ПОСЛЕДОВАТЕЛЬНОСТИ. Из онлайн-документации: объект последовательности генерирует числа в соответствии со своим определением, но объект последовательности не контролирует использование чисел. Порядковые номера, вставленные в таблицу, могут иметь пропуски при откате транзакции ... или когда порядковые номера выделяются без использования их в таблицах.

StevenJe 22.06.2020 21:18

Другие вопросы по теме