次の行の挿入に使用する予定のSQLサーバーID列の値を通知するtsqlクエリはありますか?
追加するために編集:
テーブルを削除して再作成しました
[personID] [int] IDENTITY(1,1) NOT NULL
CREATETABLEコマンドの一部として。また、そのテーブル内のすべての情報を削除しながらID列を再シードしようとしましたが、常に機能するとは限りません。次のID列番号にSQLが何を使用すると予想されるかを確認する方法があるかどうか疑問に思いました。
次の行の挿入に使用する予定のSQLサーバーID列の値を通知するtsqlクエリはありますか?
追加するために編集:
テーブルを削除して再作成しました
[personID] [int] IDENTITY(1,1) NOT NULL
CREATETABLEコマンドの一部として。また、そのテーブル内のすべての情報を削除しながらID列を再シードしようとしましたが、常に機能するとは限りません。次のID列番号にSQLが何を使用すると予想されるかを確認する方法があるかどうか疑問に思いました。
@@IDENTITY ではなく SCOPE_IDENTITY を使用して、現在のスコープの ID 値に制限することをお勧めします。これにより、トリガーによって挿入されたばかりのテーブルではなく、他のテーブルに新しい ID 値が挿入されるのを回避できます。
ただし、次の ID 値を計算することはできます
SELECT IDENT_CURRENT('mytable') + IDENT_INCR('mytable') FROM mytable
問題は、それが値であることが保証されていないことです。値が正確であることを確認するために、実行時にテーブルで他の挿入が拒否されるようにロックする必要があります。また、32ビット整数を使い果たした後、ロジックが何であるかわかりません。ロールオーバーするか失敗するかはわかりません。
編集:これをテストしたところ(SQLについては以下を参照)、データがない場合は正しい値が返されません。また、DBCC CHECKIDENT ('tablename', RESEED, 200) で再シードすると、実際には次の値が 200 ではなく 201 になりました。
CREATE TABLE willtest (myid integer IDENTITY(1,1), myvalue varchar(255))
SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest')
INSERT INTO willtest (myvalue)
VALUES ('1')
INSERT INTO willtest (myvalue)
VALUES ('2')
INSERT INTO willtest (myvalue)
VALUES ('3')
INSERT INTO willtest (myvalue)
VALUES ('4')
INSERT INTO willtest (myvalue)
VALUES ('5')
INSERT INTO willtest (myvalue)
VALUES ('6')
INSERT INTO willtest (myvalue)
VALUES ('7')
INSERT INTO willtest (myvalue)
VALUES ('8')
SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest')
DBCC CHECKIDENT ('willtest', RESEED, 200)
SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest')
INSERT INTO willtest (myvalue)
VALUES ('200')
INSERT INTO willtest (myvalue)
VALUES ('201')
INSERT INTO willtest (myvalue)
VALUES ('202')
INSERT INTO willtest (myvalue)
VALUES ('203')
INSERT INTO willtest (myvalue)
VALUES ('204')
INSERT INTO willtest (myvalue)
VALUES ('205')
INSERT INTO willtest (myvalue)
VALUES ('206')
INSERT INTO willtest (myvalue)
VALUES ('207')
SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest')
SELECT * FROM willtest
DROP TABLE willtest
いいえ、保証された方法はありません(次の値が何であるかは確かにわかりますが、別のコマンドを使用して、使用する前に使用する場合があります)。取得できる唯一の保証値は、以前に挿入されたID値ですSCOPE_IDENTITY()
(これにより、現在のスコープに対して最後に生成されたID値が返されます)。
なぜ以前に値を知る必要があるのか(自動的にインクリメントされるシードID列を使用する場合)は、どのような目的であるのか疑問です。
以前に値を知る必要がある場合は、自分でIDを生成することをお勧めします。これは、テーブル名にキーが設定されたidsテーブルを使用して行うことができます。または、スケーラビリティに懸念がある場合(およびトランザクションを使用している場合)、IDを挿入するIDを必要とするテーブルごとにIDテーブルを作成できます(その後インクリメントされます)。
または、GUIDを使用して、データベースに送信する前にクライアント側でこれらを簡単に生成できます。
このSQLは、次のID列の値を提供します(本番コードでこのスニペットを繰り返さない理由はおそらくたくさんあります)
declare @nextid int;
declare @previousid int;
begin tran
insert into dbo.TestTable (Col1) values ('11');
select @nextid = SCOPE_IDENTITY();
rollback tran
select @previousid = @nextid -1
DBCC CHECKIDENT('dbo.TestTable', RESEED, @previousid);
select @nextid
このstackoverflowの質問は、いくつかの追加情報を提供します-sql-identity-autonumber-is-incremented-even-with-a-transaction-rollback
1 からシードして 1 ずつインクリメントする (IDENTITY(1,1)) ので、「@@IDENTITY + 1 を選択」などの変数を設定できるプロシージャを作成できるかどうか疑問に思っています。
GUID
主キーには列を使用します。毎秒数十億のレコードと数千のリクエストがない限り、おそらくパフォーマンスの違いに気付かないでしょう。しかし、このようなばかげた問題に多くの時間を費やすのが好きでない限り、ストレスレベルと平均余命の違いに気付くでしょう.