Функция SQL Server для генерации последовательных чисел - PullRequest
1 голос
/ 17 августа 2011

Я хотел бы иметь функцию SQL Server dbo.GetNextNumber(), которая генерировала бы последовательные номера для каждого вызова.Насколько я понимаю, это невозможно с нативной функцией T-SQL, поскольку SQL Server настаивает, что функции должны быть детерминированными.Но, если бы вы могли показать мне встроенную функцию T-SQL, которая делает это, я действительно смогу это сделать.

Я подумал, что, возможно, это можно написать с помощью функции CLR.Так как функции CLR являются статическими, порядковые номера должны храниться в контексте вызова операции set, так как сохранение ее в качестве статической переменной приведет к тому, что несколько соединений будут использовать одну и ту же последовательность, что приведет к не очень последовательным числам.Я недостаточно знаю о встроенном CLR, чтобы увидеть, доступен ли контекст вызова операции set (select, update, delete, insert) со стороны CLR.

В конце дня следующий запрос

select dbo.GetNextNumber() from sysobjects

должен возвращать результат

1
2
3
4
5

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

exec dbo.ResetSequenceNumbers()

Чтобы предотвратить некоторые недоразумения и уменьшить шансытратить ваше время на ответ на неправильный вопрос, обратите внимание, что я не ищу функцию генерации идентификатора для таблицы, и мне известны некоторые хаки (хотя и с использованием proc, а не функции), которые включают некоторые временные таблицы со столбцами идентификаторов.Функция ROW_NUMBER() близка, но также не обрезается.

Большое спасибо за любые ответы

Kemal

PS Удивительно, что SQL Server действительно имеет встроеннуюв функции для этого.Функция (при условии, что ее нельзя использовать в объединениях и выражениях), действительно проста и чрезвычайно полезна, но по какой-то причине она не включена.

Ответы [ 4 ]

5 голосов
/ 18 августа 2011

Поскольку вы реализовали последовательность CLR на основе моей статьи, связанной с вычислением промежуточных итогов, вы можете добиться того же, используя функцию ROW_NUBER().

ROW_NUMBER()функция требует ORDER BY в предложении OVER, однако есть хороший обходной путь, как избежать сортировки из-за ORDER BY.Вы не можете поместить выражение в порядке, но вы можете поместить SELECT aConstant там.Таким образом, вы можете легко добиться генерации чисел, используя следующую инструкцию.

SELECT
    ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNumber,
    *
FROM aTable
2 голосов
/ 17 августа 2011

Можете ли вы дать больше информации о том, почему ROW_NUMBER() не сокращает его? В приведенном вами конкретном примере ROW_NUMBER() (с соответствующим уточнением OVER(ORDER BY)) определенно соответствует вашим критериям.

Но, безусловно, существуют случаи, когда ROW_NUMBER() может оказаться бесполезным, и в этих случаях обычно используются другие методы.

Возможно, эта общая функция кажется вам полезной, но в большинстве случаев я считаю, что решение, лучше приспособленное к рассматриваемой проблеме, - это лучшая идея, чем функция общего назначения, которая в конечном итоге вызывает больше трудностей - как, например, утечка абстракции. постоянно работают вокруг. Вы специально упоминаете о необходимости иметь функцию сброса. С ROW_NUMBER() такая вещь не требуется, поскольку она имеет OVER(PARTITION BY ORDER BY), которая позволяет вам указать группировку.

2 голосов
/ 17 августа 2011

В следующей версии SQL Server вы можете использовать ПОСЛЕДОВАТЕЛЬНОСТЬ для этого. В более ранних версиях это достаточно просто сделать, вставив в отдельную «таблицу последовательностей» (таблицу только с столбцом IDENTITY), а затем получив значение с помощью функции SCOPE_IDENTITY (). Вы не сможете сделать это в функции, но вы можете использовать хранимую процедуру.

0 голосов
/ 18 августа 2011

SQL Server Denali имеет новую структуру последовательности для разработчиков После Денали легко управлять и поддерживать порядковые номера в SQL Server Вы можете найти подробности в порядковых номерах в SQL Server

Для других версий, кроме Denali, вы можете использовать таблицы последовательности. Вот пример для таблицы последовательности в SQL Server Для чтения порядкового номера из таблицы последовательности необходимо вставить фиктивные записи из таблицы sql с включенной автоматической идентификацией

...