1

トランザクション レプリケーションを使用して、一連のテーブルを SQL Server 2008 から新しい SQL Server 2012 マシンに移行しました。これまでのところ問題なく機能しており、複製されたデータが元のデータと同じになるように、インデックスとデフォルト値も複製しました。

新しいマシンをレプリケーションから切り離して、古いマシンの代わりとしてスタンドアロンとして機能させると、SQL Server が ID 列のすべてのギャップを埋め始め、さまざまな問題を引き起こす可能性があります。つまり、私のコードは、最後に挿入された行の最高の ID を持つことに頼ることができなくなりました。また、以前に削除されたユーザー ID が再利用されるため、ユーザー側でも混乱が生じる可能性があります。

DB の新しいインスタンスを古いレプリケートされたものとまったく同じように動作させる方法はありますか? 私の経験では、データベースの実行中のインスタンスが、以前に削除された行のギャップを埋めることはありません。

4

1 に答える 1

1

これも見たことがない。ただし、展開時にテーブルが 0 に再シードされる可能性があります。次の例を確認してください。

SET NOCOUNT ON;
GO
CREATE TABLE dbo.fooblat(id INT IDENTITY(1,1));
GO
INSERT dbo.fooblat DEFAULT VALUES;
GO 3
DELETE dbo.fooblat WHERE id = 2;
GO
DBCC CHECKIDENT('dbo.fooblat', RESEED, 0);
GO
INSERT dbo.fooblat DEFAULT VALUES;
GO 3
SELECT id FROM dbo.fooblat ORDER BY id;
GO
DROP TABLE dbo.fooblat;

結果:

id
----
1
1
2
3
3

ここで、ID 列も主キーまたは一意である場合、この同じ操作でギャップが埋められる可能性があり、重複違反のみが失敗します。したがって、このテーブル定義でもう一度繰り返します。

CREATE TABLE dbo.fooblat(id INT IDENTITY(1,1) PRIMARY KEY);
GO

これが得られます (最初に成功した挿入がギャップを埋めました):

id
----
1
2
3

メッセージ 2627、レベル 14、状態 1、行 1
PRIMARY KEY 制約 'PK_ fooblat _3213E83F6BF0A0C6' の違反。オブジェクト 'dbo.fooblat' に重複するキーを挿入できません。重複キーの値は (1) です。
メッセージ 2627、レベル 14、状態 1、行 1
PRIMARY KEY 制約 'PK_ fooblat _3213E83F6BF0A0C6' の違反。オブジェクト 'dbo.fooblat' に重複するキーを挿入できません。重複キーの値は (3) です。

この状況を回避するには、テーブルが他のシステムに配置されるときにテーブルが正しくシードされるようにします。これは、より信頼性の高い展開手法を使用することを意味する場合もあれば、データを入力した後、ユーザーを入れる前に、次のようなことを行うことを意味する場合もあります。

DECLARE @i INT, @sql NVARCHAR(MAX);
SELECT @i = MAX(id) FROM dbo.fooblat;
SET @sql = N'DBCC CHECKIDENT(''dbo.fooblat'', RESEED, ' + RTRIM(@i) + ');';
EXEC sp_executesql @sql;
于 2013-02-13T02:08:26.187 に答える