9

ID セットを持つ SQL テーブルがあります。

CREATE TABLE MyTable(
    MyTableID int IDENTITY(1,1) NOT NULL,
    RecordName nvarchar(100) NULL)

このテーブルに何かが発生したため、異常な動作が発生しました。私は何を見つける必要があります。

挿入が発生すると:

INSERT MyTable(RecordName) 
VALUES('Test Bug')

SELECT SCOPE_IDENTITY() -- returns 0
SELECT * FROM MyTable   -- displays: 0, 'Test Bug'

この挿入の上のコードは最初の ID が であることを想定しているため、これは1問題IDENTITY(1,1)です0

(を実行する前にINSERT)IDを確認すると、nullが返されます:

DBCC CHECKIDENT (MyTable, NORESEED)

ID 情報をチェックしています: 現在の ID 値 'NULL'、現在の列値 'NULL'。

これを修正する方法はいくつか知っています。そもそもテーブルがどのようにしてこの状態になったのかを知る必要があるのは何ですか?

null を返すことがわかっている唯一の方法CHECKIDENTは、テーブルが作成されたばかりの場合ですが、それIDENTITY(1,1)が尊重され、INSERT原因SCOPE_IDENTITY()1.

別の方法として、現在のシード (または with ) として0強制すると、次の ID として取得できますが、チェックは現在のシード (null ではなく) を報告するため、これは起こり得ません。-1DBCC CHECKIDENT (MyTable, RESEED, -1)SET IDENTITY_INSERT MyTable ON-1

データベースはどのようにして、列がnull を返し、次のIDENTITY(1,1)原因がになる状態になったのでしょうか?DBCC CHECKIDENT (MyTable, NORESEED)INSERTSCOPE_IDENTITY()0

4

1 に答える 1

15

誰か/何かが実行されたと思います:

DBCC CHECKIDENT ('dbo.MyTable', RESEED, 0);

以下を実行する場合:

CREATE TABLE dbo.MyTable(
    MyTableID int IDENTITY(1,1) NOT NULL,
    RecordName nvarchar(100) NULL
);

DBCC CHECKIDENT ('dbo.MyTable', RESEED, 0);
DBCC CHECKIDENT ('dbo.MyTable', NORESEED);

2番目CHECKIDENTはまだ戻りますNULL

ID 情報をチェックしています: 現在の ID 値 'NULL'、現在の列値 'NULL'。

ただし、次の ID 値は 0 になります。これは文書化された動作であり、MSDN は次のように述べています。

現在の ID 値は、new_reseed_value に設定されます。テーブルが作成されてから行が挿入されていない場合、DBCC CHECKIDENT の実行後に挿入される最初の行は、 new_reseed_value を ID として使用します。それ以外の場合、挿入される次の行は new_reseed_value + 1 を使用します。new_reseed_value の値が ID 列の最大値より小さい場合、テーブルへの後続の参照でエラー メッセージ 2627 が生成されます。

last_valueこれは、列sys.identity_columnsがまだ NULLである、新しく作成された/切り捨てられたテーブルでのみ機能します。上記のように、行を挿入して削除し、次に 0 に再シードした場合、新しい ID は 1 のままです。

完全なテスト スクリプト

IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
    DROP TABLE dbo.T;

CREATE TABLE dbo.T(ID INT IDENTITY(1,1) NOT NULL);
INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
-- OUTPUTS 1

DELETE dbo.T;
DBCC CHECKIDENT ('dbo.T', RESEED, 0);
INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
-- OUTPUTS 1

TRUNCATE TABLE dbo.T;
DBCC CHECKIDENT ('dbo.T', RESEED, 0);
INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
-- OUTPUTS 0
于 2014-03-05T14:32:09.020 に答える