理想的な状況とはほど遠いですが、他の 4 つのテーブルとの FK リレーションを持つ PK Identiy 列に数字「1」を追加して、データベースを修正する必要があります。私は基本的に4桁の数字を5桁の数字にしています。関係を維持する必要があります。数値を var に格納し、Set クエリを実行して 1 を追加し、テーブルごとにそれを行うことができます...
これを行うより良い方法はありますか?
理想的な状況とはほど遠いですが、他の 4 つのテーブルとの FK リレーションを持つ PK Identiy 列に数字「1」を追加して、データベースを修正する必要があります。私は基本的に4桁の数字を5桁の数字にしています。関係を維持する必要があります。数値を var に格納し、Set クエリを実行して 1 を追加し、テーブルごとにそれを行うことができます...
これを行うより良い方法はありますか?
主キーにデータ型を使用していると言うidentity
ので、数値を更新する前にSET IDENTITY_INSERT ON
(ドキュメントはこちら)、更新後に再びオフにする必要があります。
リレーションにカスケード更新が設定されている限り、他のテーブルは自動的に更新されます。
編集: ID 値を変更することはできないため、データをエクスポートし、新しい ID 値 (+10000) を設定してから、データを再度インポートする必要があると思います。
誰でも良い案が...
問題の列にIDプロパティがある場合、複雑になります。これは多かれ少なかれ私がそれをする方法です:
データベースをバックアップします。
シングルユーザーモードにします。あなたが手術をしている間、あなたはだれもいじくり回す必要はありません。
ALTER TABLE
に必要なステートメントを実行します
テーブルのクローンを作成し、新しい名前と列ごとに同じ定義を付けます。トリガー、インデックス、外部キー、またはその他の制約を気にしないでください。テーブルの定義からidentityプロパティを省略します。
古いid値を新しい値にマップする新しい'map'テーブルを作成します。
create table dbo.pk_map
(
old_id int not null primary key clustered ,
new_id int not null unique nonclustered ,
)
マップテーブルにデータを入力します。
insert dbo.pk_map
select old_id = old.id ,
new_id = f( old.id ) // f(x) is the desired transform
from dbo.tableInQuestion old
新しいテーブルにデータを入力し、主キー列に新しい値を指定します。
insert dbo.tableInQuestion_NEW
select id = map.id ,
...
from dbo.tableInQuestion old
join dbo.pk_map map on map.old_id = old.id
元のテーブルを切り捨てます:TRUNCATE dbo.tableInQuestion
。すべてのトリガーと外部キー制約を無効にしているので、これは安全に機能するはずです。
実行しSET IDENTITY_INSERT dbo.tableInQuestion ON
ます。
元のテーブルをリロードします。
insert dbo.tableInQuestion
select *
from dbo.tableInQuestion_NEW
実行するSET IDENTITY_INSERT dbo.tableInQuestion OFF
実行しdrop table dbo.tableInQuestion_NEW
ます。これですべて完了です。
実行DBCC CHECKIDENT( dbo.tableInQuestion , reseed )
して、IDカウンターをテーブル内のデータと同期させます。
次に、マップテーブルを使用して、変更された主キー列を次の行に伝播します。ERモデルによっては、更新された列を参照する外部キー自体が複合主キーの一部である可能性があるため、これは複雑になる可能性があります。
すべて完了したら、無効にした制約とトリガーを再度有効にします。WITH CHECK
オプションを使用してこれを行うようにしてください。このようにして発見された問題を修正します。
最後に、マップテーブルを削除し、シングルユーザーフラグをクリアして、システムをオンラインに戻します。
ケーキ!(か何か。)
私の提案は次のとおりです。
事後に PK を変更するのは楽しくありません。
PK フィールドの長さを延長する代わりに、別のフィールドを PK に追加することを検討してください。フィールドの長さを増やす場合と同様に、新しいフィールドを関連するテーブルにカスケードする必要がありますが、元の PK 値を保持できます。
このアプローチを検討してください。IDシードを10000+現在のシードにリセットします。テーブルの値からテーブルへの挿入にID挿入を設定し、途中でID列に10000を追加します。元:
Set identity insert on
Insert Table(identity, column1, eolumn2)
select identity + 10000, column1, column2
From Table
Where identity < origional max identity value
挿入後、IDが元のIDよりも正確に10000多いことがわかります。10000を追加して、外部キーを更新します。