NEXT VALUE FOR (Transact-SQL)
指定したシーケンス オブジェクトからシーケンス番号を生成します。
シーケンスの作成と使用の詳細については、「シーケンス番号」を参照してください。シーケンス番号の範囲を生成するには、sp_sequence_get_range を使用します。
適用対象: SQL Server (SQL Server 2012 から現在のバージョンまで)、SQL Database V12。 |
構文
NEXT VALUE FOR [ database_name . ] [ schema_name . ] sequence_name
[ OVER (<over_order_by_clause>) ]
引数
database_name
シーケンス オブジェクトを含むデータベースの名前を指定します。schema_name
シーケンス オブジェクトを含むスキーマの名前を指定します。sequence_name
番号を生成するシーケンス オブジェクトの名前を指定します。over_order_by_clause
シーケンス値がパーティション内の行に割り当てられる順序を決定します。詳細については、「OVER 句 (Transact-SQL)」を参照してください。
戻り値の型
シーケンスの型を使用して数値を返します。
解説
NEXT VALUE FOR 関数は、ストアド プロシージャやトリガーで使用できます。
NEXT VALUE FOR 関数をクエリや既定の制約で使用する場合、同じシーケンス オブジェクトを 2 回以上使用する、または値を提供するステートメントと実行中の既定の制約の両方で同じシーケンス オブジェクトを使用すると、結果セットの行内の同じシーケンスを参照するすべての列に対して同じ値が返されます。
NEXT VALUE FOR 関数は非決定的で、生成されるシーケンス値の数が適切に定義されているコンテキストでのみ使用できます。特定のステートメントにおいて、参照されている各シーケンス オブジェクトに使用される値の数の定義を以下に示します。
SELECT - 参照されている各シーケンス オブジェクトに対して、ステートメントの結果内の行ごとに新しい値が 1 回生成されます。
INSERT …VALUES - 参照されている各シーケンス オブジェクトに対して、ステートメント内の挿入された行ごとに新しい値が 1 回生成されます。
UPDATE - 参照されている各シーケンス オブジェクトに対して、ステートメントによって更新された行ごとに新しい値が 1 回生成されます。
手続き型ステートメント (DECLARE、SET など)- 参照されている各シーケンス オブジェクトに対して、ステートメントごとに新しい値が生成されます。
制限事項と制約事項
NEXT VALUE FOR 関数は、次の状況では使用できません。
データベースが読み取り専用モードの場合。
テーブル値関数の引数として使用する場合。
集計関数の引数として使用する場合。
共通テーブル式および派生テーブルを含むサブクエリ内で使用する場合。
ビュー、ユーザー定義関数、または計算列内で使用する場合。
DISTINCT、UNION、UNION ALL、EXCEPT、または INTERSECT 演算子を使用するステートメント内で使用する場合。
NEXT VALUE FOR …OVER (ORDER BY …)が使用される場合を除き、ORDER BY 句を使用するステートメント内で使用する場合。
FETCH、OVER、OUTPUT、ON、PIVOT、UNPIVOT、GROUP BY、HAVING、COMPUTE、COMPUTE BY、FOR XML の各句で使用する場合。
CASE、CHOOSE、COALESCE、IIF、ISNULL、または NULLIF を使用する条件式内で使用する場合。
VALUES ステートメントの一部ではない INSERT 句で使用する場合。
CHECK 制約の定義で使用する場合。
ルールまたは既存のオブジェクトの定義で使用する場合 (既定の制約では使用できます)。
既定では、ユーザー定義テーブル型で使用します。
TOP、OFFSET を使用するか、ROWCOUNT オプションが設定されているステートメントで使用する場合。
ステートメントの WHERE 句で使用する場合。
MERGE ステートメントで使用する場合。ただし、NEXT VALUE FOR 関数が対象のテーブルの既定の制約で使用され、CREATE ステートメントの MERGE ステートメントで既定値が使用されている場合を除きます。
既定の制約でのシーケンス オブジェクトの使用
既定の制約で NEXT VALUE FOR 関数を使用する場合、次のルールが適用されます。
複数のテーブル内の既定の制約から 1 つのシーケンス オブジェクトを参照できます。
テーブルとシーケンス オブジェクトは同じデータベースに置く必要があります。
既定の制約を追加するユーザーには、シーケンス オブジェクトに対する REFERENCES 権限が必要です。
既定の制約を削除する前に、既定の制約から参照されているシーケンス オブジェクトを削除できません。
複数の既定の制約で同じシーケンス オブジェクトを使用する場合、または値を提供するステートメントと実行中の既定の制約の両方で同じシーケンス オブジェクトを使用する場合、行内のすべての列に対して同じシーケンス番号が返されます。
既定の制約での NEXT VALUE FOR 関数への参照では、OVER 句を指定できません。
既定の制約で参照されているシーケンス オブジェクトは変更できます。
INSERT … SELECT ステートメントまたは INSERT … EXEC ステートメントで、挿入されるデータを ORDER BY 句を使用してクエリから取得する場合、NEXT VALUE FOR 関数によって返される値は、ORDER BY 句で指定された順序で生成されます。
OVER ORDER BY 句でのシーケンス オブジェクトの使用
NEXT VALUE FOR 関数では、OVER の呼び出しに NEXT VALUE FOR 句を適用することで並べ替えられたシーケンス値の生成をサポートしています。OVER 句を使用することにより、返される値が OVER 句の ORDER B サブ句の順序で生成されることが保証されます。NEXT VALUE FOR 関数を OVER 句と共に使用する場合、次の追加ルールが適用されます。
1 つのステートメントで同じシーケンス ジェネレーターに対して NEXT VALUE FOR 関数を複数回呼び出す場合は、すべての呼び出しで同じ OVER 句の定義を使用する必要があります。
1 つのステートメントで異なるシーケンス ジェネレーターを参照する NEXT VALUE FOR 関数を複数回呼び出す場合は、異なる OVER 句の定義を使用できます。
OVER 関数に適用される NEXT VALUE FOR 句では、PARTITION BY サブ句を使用できません。
NEXT VALUE FOR ステートメント内の SELECT 関数のすべての呼び出しで OVER 句を指定する場合は、その ORDER BY ステートメントで SELECT 句を使用できます。
OVER ステートメントまたは NEXT VALUE FOR ステートメントでは、SELECT 関数と共に INSERT … SELECT … 句を使用できます。NEXT VALUE FOR 関数は、UPDATE ステートメントおよび MERGE ステートメントでは使用できません。
別のプロセスが同時にシーケンス オブジェクトにアクセスしている場合は、非連続的な番号が返される可能性があります。
メタデータ
シーケンスに関する情報を取得するには、sys.sequences カタログ ビューに対してクエリを実行します。
セキュリティ
権限
シーケンス オブジェクトまたはシーケンスのスキーマに対する UPDATE 権限が必要です。権限を付与する例については、後の例 F を参照してください。
組み合わせ所有権
シーケンス オブジェクトでは、組み合わせ所有権をサポートしています。シーケンス オブジェクトの所有者が、(既定の制約としてシーケンス オブジェクトを所有する) 呼び出し元のストアド プロシージャ、トリガー、またはテーブルと同じ場合、シーケンス オブジェクトに対する権限チェックは必要ありません。シーケンス オブジェクトの所有者が、呼び出し元のストアド プロシージャ、トリガー、またはテーブルと異なる場合、シーケンス オブジェクトに対する権限チェックが必要です。
NEXT VALUE FOR 関数をテーブルで既定値として使用している場合、既定値を使用してデータを挿入するには、そのテーブルに対する INSERT 権限とシーケンス オブジェクトに対する UPDATE 権限の両方が必要です。
既定の制約の所有者がシーケンス オブジェクトと同じ場合、既定の制約を呼び出す際に、シーケンス オブジェクトに対する権限は必要ありません。
既定の制約の所有者がシーケンス オブジェクトと異なる場合、既定の制約を使用してシーケンス オブジェクトを呼び出す際にも、シーケンス オブジェクトに対する権限が必要です。
監査
NEXT VALUE FOR 関数を監査するには、SCHEMA_OBJECT_ACCESS_GROUP を監視します。
使用例
シーケンスを作成し、NEXT VALUE FOR 関数を使用してシーケンス番号を生成する例については、「シーケンス番号」を参照してください。
次の例では、CountBy1 という名前のスキーマの Test という名前のシーケンスを使用します。次のステートメントを実行して、Test.CountBy1 シーケンスを作成します。例 C および E では、 AdventureWorks2012 データベースを使用します。そのため、CountBy1 シーケンスはそのデータベースに作成されます。
USE AdventureWorks2012 ;
GO
CREATE SCHEMA Test;
GO
CREATE SEQUENCE Test.CountBy1
START WITH 1
INCREMENT BY 1 ;
GO
A.SELECT ステートメントでシーケンスを使用する
次の例では、使用されるたびに 1 つずつ増加する CountBy1 という名前のシーケンスを作成します。
SELECT NEXT VALUE FOR Test.CountBy1 AS FirstUse;
SELECT NEXT VALUE FOR Test.CountBy1 AS SecondUse;
以下に結果セットを示します。
FirstUse
1
SecondUse
2
B.変数に次のシーケンス値を設定する
次の例では、変数にシーケンス番号の次の値を設定する 3 つの方法を示します。
DECLARE @myvar1 bigint = NEXT VALUE FOR Test.CountBy1
DECLARE @myvar2 bigint ;
DECLARE @myvar3 bigint ;
SET @myvar2 = NEXT VALUE FOR Test.CountBy1 ;
SELECT @myvar3 = NEXT VALUE FOR Test.CountBy1 ;
SELECT @myvar1 AS myvar1, @myvar2 AS myvar2, @myvar3 AS myvar3 ;
GO
C.順位付け関数と共にシーケンスを使用する
USE AdventureWorks2012 ;
GO
SELECT NEXT VALUE FOR Test.CountBy1 OVER (ORDER BY LastName) AS ListNumber,
FirstName, LastName
FROM Person.Contact ;
GO
D.既定の制約の定義で NEXT VALUE FOR 関数を使用する
既定の制約の定義では、NEXT VALUE FOR 関数を使用できます。NEXT VALUE FOR ステートメントで CREATE TABLE を使用する例については、「シーケンス番号」の例 C を参照してください。次の例では、ALTER TABLE を使用して、シーケンスを既定値として現在のテーブルに追加します。
CREATE TABLE Test.MyTable
(
IDColumn nvarchar(25) PRIMARY KEY,
name varchar(25) NOT NULL
) ;
GO
CREATE SEQUENCE Test.CounterSeq
AS int
START WITH 1
INCREMENT BY 1 ;
GO
ALTER TABLE Test.MyTable
ADD
DEFAULT N'AdvWorks_' +
CAST(NEXT VALUE FOR Test.CounterSeq AS NVARCHAR(20))
FOR IDColumn;
GO
INSERT Test.MyTable (name)
VALUES ('Larry') ;
GO
SELECT * FROM Test.MyTable;
GO
E.INSERT ステートメントで NEXT VALUE FOR 関数を使用する
次の例では、TestTable という名前のテーブルを作成した後、NEXT VALUE FOR 関数を使用して、行を挿入します。
CREATE TABLE Test.TestTable
(CounterColumn int PRIMARY KEY,
Name nvarchar(25) NOT NULL) ;
GO
INSERT Test.TestTable (CounterColumn,Name)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Syed') ;
GO
SELECT * FROM Test.TestTable;
GO
E.SELECT … と共に NEXT VALUE FOR 関数を使用するINTO
次の例では、SELECT … INTO ステートメントを使用して Production.NewLocation という名前のテーブルを作成し、 NEXT VALUE FOR 関数を使用して各行に番号を付けます。
USE AdventureWorks2012 ;
GO
SELECT NEXT VALUE FOR Test.CountBy1 AS LocNumber, Name
INTO Production.NewLocation
FROM Production.Location ;
GO
SELECT * FROM Production.NewLocation ;
GO
F.NEXT VALUE FOR を実行する権限を付与する
次の例では、Test.CounterSeq シーケンスを使用して、NEXT VALUE FOR を実行できるように、AdventureWorks\Larry という名前のユーザーに UPDATE 権限を付与します。
GRANT UPDATE ON OBJECT::Test.CounterSeq TO [AdventureWorks\Larry] ;
参照
CREATE SEQUENCE (Transact-SQL)
ALTER SEQUENCE (Transact-SQL)
シーケンス番号