NEXT VALUE FOR: примеры (SQL)
NEXT VALUE FOR(sequence_name): Depends on sequenceОписание функции NEXT VALUE FOR
Функция NEXT VALUE FOR используется для получения следующего значения из заданной последовательности (SEQUENCE) в Microsoft SQL Server. Последовательности представляют собой объекты базы данных, генерирующие упорядоченные числовые значения согласно заданным правилам.
Функция применяется в запросах SELECT, INSERT, а также при определении значения по умолчанию для столбца таблицы. Она позволяет централизованно управлять генерацией уникальных ключей и номеров, независимо от конкретных таблиц.
Основные аргументы и параметры относятся к самому объекту SEQUENCE, который создается отдельно. Функция NEXT VALUE FOR принимает только имя последовательности в качестве аргумента:
- sequence_name — имя созданной последовательности в схеме базы данных.
Возвращаемое значение соответствует типу данных, указанному при создании последовательности (обычно bigint, int, smallint, tinyint, decimal или numeric). Каждый вызов функции увеличивает текущее значение последовательности в соответствии с заданным шагом (INCREMENT).
Функция является недетерминированной — каждый новый вызов в рамках транзакции или запроса возвращает новое значение. Поведение функции внутри транзакций зависит от использования флагов CACHE и циклического перезапуска.
Базовые примеры использования
Пример создания простой последовательности и получения значений:
CREATE SEQUENCE Seq_OrderNumber AS INT START WITH 1 INCREMENT BY 1;Получение следующего значения:
SELECT NEXT VALUE FOR Seq_OrderNumber;1
Последующий вызов:
SELECT NEXT VALUE FOR Seq_OrderNumber;2
Использование в INSERT:
CREATE TABLE Orders (ID INT, OrderNum INT);
INSERT INTO Orders (ID, OrderNum)
VALUES (1, NEXT VALUE FOR Seq_OrderNumber);Использование с флагами MINVALUE и MAXVALUE:
CREATE SEQUENCE Seq_Cyclic AS INT
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 3
CYCLE;
SELECT NEXT VALUE FOR Seq_Cyclic;
SELECT NEXT VALUE FOR Seq_Cyclic;
SELECT NEXT VALUE FOR Seq_Cyclic;
SELECT NEXT VALUE FOR Seq_Cyclic;1
2
3
1
Альтернативные методы генерации значений в MS SQL
IDENTITY — свойство столбца таблицы, автоматически увеличивающее значение при вставке новой строки. Применяется непосредственно при создании таблицы. Идеально подходит для простых сценариев, где уникальный ключ требуется только для одной таблицы. Не позволяет управлять последовательностью извне или использовать одно значение для нескольких таблиц.
NEWID() и NEWSEQUENTIALID() — функции для генерации уникальных глобальных идентификаторов (GUID). Используются, когда необходим уникальный ключ в распределенных системах или при объединении данных из разных источников. Значения не являются последовательными числами.
ROW_NUMBER() — оконная функция, генерирующая порядковый номер строки в рамках заданной секции результирующего набора. Не сохраняет состояние между запросами и используется только для нумерации строк в результатах SELECT.
Выбор подхода зависит от требований: SEQUENCE с NEXT VALUE FOR предпочтительнее для сложных бизнес-номеров, общих для нескольких таблиц, в то время как IDENTITY проще для автоинкрементных первичных ключей.
Аналоги функции в других СУБД
PostgreSQL: Используется выражение nextval('sequence_name'). Поведение и концепция схожи с MS SQL.
CREATE SEQUENCE seq_example;
SELECT nextval('seq_example');1
Oracle: Аналогично используется sequence_name.NEXTVAL. Последовательности часто применяются для генерации первичных ключей.
CREATE SEQUENCE seq_example;
SELECT seq_example.NEXTVAL FROM dual;1
MySQL: Не имеет прямого аналога SEQUENCE до версии 8.0. В версии 8.0 появилась поддержка SEQUENCE. Традиционно используется AUTO_INCREMENT для столбцов таблицы.
-- MySQL 8.0 и выше
CREATE SEQUENCE seq_example;
SELECT NEXT VALUE FOR seq_example;SQLite: Отсутствуют объекты SEQUENCE. Для автоинкремента используется ключевое слово AUTOINCREMENT для столбца INTEGER PRIMARY KEY.
Sybase ASE: Поддерживает IDENTITY, но не объекты SEQUENCE в том виде, как в MS SQL. Используются системные функции для получения идентификаторов.
Распространенные ошибки
1. Попытка использовать несуществующую последовательность.
SELECT NEXT VALUE FOR NonExistentSeq;Сообщение 11730, уровень 16, состояние 1...
Объект последовательности 'NonExistentSeq' не существует.
2. Использование в контексте, где функция не допускается, например в CHECK-ограничении, представлении с WITH CHECK OPTION, в функции, возвращающей скалярное значение.
CREATE FUNCTION GetNextVal()
RETURNS INT
AS
BEGIN
RETURN NEXT VALUE FOR Seq_OrderNumber;
END;Недопустимо использовать NEXT VALUE FOR в данной контексте.
3. Исчерпание диапазона значений последовательности с флагом NO CYCLE.
CREATE SEQUENCE Seq_NoCycle AS TINYINT
START WITH 254
INCREMENT BY 1
NO CYCLE;
SELECT NEXT VALUE FOR Seq_NoCycle; -- 254
SELECT NEXT VALUE FOR Seq_NoCycle; -- 255
SELECT NEXT VALUE FOR Seq_NoCycle; -- ОшибкаСообщение 11728, уровень 16...
Превышено предельное значение для последовательности...
История изменений
Функция NEXT VALUE FOR была введена в Microsoft SQL Server начиная с версии 2012 (11.x). До этой версии объекты SEQUENCE и соответствующая функция отсутствовали, а для генерации последовательных значений использовались преимущественно IDENTITY или отдельные таблицы-счетчики.
В более поздних версиях существенных изменений в синтаксисе или поведении функции не было. Однако в рамках общей поддержки последовательностей были улучшения, связанные с производительностью и интеграцией с другими функциями ядра СУБД. Основные возможности, такие как CACHE, CYCLE, MINVALUE/MAXVALUE, присутствовали с момента реализации.
Расширенные примеры
Использование в значении по умолчанию для столбца:
CREATE SEQUENCE Seq_Def AS INT START WITH 1000;
CREATE TABLE Documents (
DocID INT PRIMARY KEY,
DocNumber INT DEFAULT (NEXT VALUE FOR Seq_Def)
);
INSERT INTO Documents (DocID) VALUES (1);
SELECT * FROM Documents;DocID DocNumber
1 1000
Общая последовательность для нескольких таблиц:
CREATE SEQUENCE Seq_UniversalInvoice AS INT START WITH 50000;
CREATE TABLE Invoices2023 (ID INT, InvNum INT);
CREATE TABLE Invoices2024 (ID INT, InvNum INT);
INSERT INTO Invoices2023 VALUES (1, NEXT VALUE FOR Seq_UniversalInvoice);
INSERT INTO Invoices2024 VALUES (1, NEXT VALUE FOR Seq_UniversalInvoice);
SELECT * FROM Invoices2023 UNION ALL SELECT * FROM Invoices2024;ID InvNum
1 50000
1 50001
Использование с большим кэшем для производительности вставки большого объема данных:
CREATE SEQUENCE Seq_Fast WITH CACHE = 1000;
-- При частых вызовах NEXT VALUE FOR значения будут браться из кэша в памяти,
-- что снижает количество обращений к системным таблицам.Сброс последовательности с помощью ALTER SEQUENCE:
CREATE SEQUENCE Seq_Reset AS INT START WITH 1;
SELECT NEXT VALUE FOR Seq_Reset; -- 1
SELECT NEXT VALUE FOR Seq_Reset; -- 2
ALTER SEQUENCE Seq_Reset RESTART WITH 10;
SELECT NEXT VALUE FOR Seq_Reset; -- 101
2
10
Использование в сочетании с OVER() для нумерации строк в запросе (начиная с SQL Server 2022).