документация для SCOPE_IDENTITY
утверждает, что это
Возвращает последнее значение идентификатора, вставленное в столбец идентификаторов в той же области.
Интересно, что на самом деле означает last
. Является ли это самым большим значением, вставленным в текущую область, или значением строки, которая была физически последней вставленной в таблицу?
Я пытался
- create table with
IDENTITY
as a clustered index- this worked as expected; return value of
SCOPE_IDENTITY
was the highest value of identity column inserted
- this worked as expected; return value of
- create table with
IDENTITY
as a column with different column as a cluster- i tried to use different
ORDER BY
statements to make sure that the generatedIDENTITY
didn't match the clustered index in any way SCOPE_IDENTITY
всегда возвращал максимальное достигнутое значение столбцаIDENTITY
, даже если идентификаторы генерировались независимо от кластеризованного индекса.
- i tried to use different
- Я не пробовал таблицу с кучей
Почему я спрашиваю: я наткнулся на фрагмент кода, который вставляет несколько строк и использует SCOPE_IDENTITY
для вставки самого высокого идентификатора, с которым он затем что-то выполняет. Учитывая то, как работает SCOPE_IDENTITY
, в настоящее время он работает нормально, но мне интересно, может ли он привести к неожиданным ошибкам.
Мой вопрос:
Должен ли я всегда предполагать, что SCOPE_IDENTITY
возвращает наибольшее значение вставленного IDENTITY
(для возрастания IDENTITY), независимо от того, как строки были физически или логически вставлены в таблицу? Или я должен просто использовать OUTPUT
, а затем MAX
в столбце идентификаторов, чтобы быть уверенным?
Изменить: чтобы поместить это в код, всегда ли следующий код будет приводить к этому. Это происходит каждый раз, независимо от того, что находится в CREATE TABLE #WithID
, SELECT
, FROM
, WHERE
или ORDER BY
? Предполагая, что ID INTEGER IDENTITY(1,1)
остается постоянным.
CREATE TABLE #WithID (ID INTEGER IDENTITY(1,1), SomeData INTEGER);
CREATE TABLE #Outputs (ID INTEGER);
INSERT INTO #WithID
OUTPUT Inserted.ID INTO #Outputs
SELECT Number
FROM dbo.Numbers
WHERE Number < 1000000
ORDER BY Number;
IF SCOPE_IDENTITY() = (SELECT MAX(ID) FROM #Outputs)
PRINT 'This happens everytime'
ELSE
PRINT 'Oops...';
note: Я не знаю, насколько хорошо известно, что значения, созданные IDENTITY, создаются в порядке ORDER BY
предложения SELECT
, а не в том порядке, в котором строки физически вставляются в таблицу.
Is it the largest value inserted in current scope, or the value of row that was physically last inserted into the table
— эти две категории одинаковы, потому что идентификатор — это постоянно увеличивающееся значение, поэтому последняя вставленная строка будет иметь самый большой идентификатор текущей вставленной группы. И если вы предоставляете предварительно рассчитанные идентификаторы, то вам вообще не нуженscope_identity()
. - person GSerg   schedule 09.06.2021IDENTITY
, где значение постоянно уменьшается, и вышеприведенное не будет правдой, @GSerg . :) db‹›fiddle - person Larnu   schedule 09.06.2021IDENTITY
может быть сброшена. В любом случае, зачем вам это делать, что Oops вы пытаетесь поймать, и кого волнует, является ли последнее значениеIDENTITY
самым высоким в таблице? - person Charlieface   schedule 09.06.2021INSERT
. Я предполагаю, что сбросIDENTITY
является изменением схемы и что это не могло произойти во время выполненияINSERT
. Упс было бы, если быSCOPE_IDENTITY
вернуло, т.е. 10, но самое большое вставленноеIDENTITY
было 20. - person andowero   schedule 09.06.2021SCOPE_IDENTITY
не будет использоваться для идентификации одной строки, его, вероятно, не следует использовать. Для явных операций, требующих резервирования непрерывного диапазона значений или позволяющих делать предположения о значениях, используйте последовательности; для операций, которые хотят начать с текущего наибольшего значения, используйтеMAX(ID)
как можно ближе к точке запроса, которая требует этого (что имеет то преимущество, что вы можете сделать его атомарным). - person Jeroen Mostert   schedule 09.06.2021order by
будет учитываться во вставке, если она относится к столбцу идентификаторов (с целью назначения идентификаторов), это не соответствует порядку физических записей в таблице.scope_identity()
возвращает последний (самый большой*) значение идентификатора, сгенерированное для набора. - person GSerg   schedule 09.06.2021