3

理想的な状況とはほど遠いですが、他の 4 つのテーブルとの FK リレーションを持つ PK Identiy 列に数字「1」を追加して、データベースを修正する必要があります。私は基本的に4桁の数字を5桁の数字にしています。関係を維持する必要があります。数値を var に格納し、Set クエリを実行して 1 を追加し、テーブルごとにそれを行うことができます...

これを行うより良い方法はありますか?

4

5 に答える 5

2

主キーにデータ型を使用していると言うidentityので、数値を更新する前にSET IDENTITY_INSERT ONドキュメントはこちら)、更新後に再びオフにする必要があります。

リレーションにカスケード更新が設定されている限り、他のテーブルは自動的に更新されます。

編集: ID 値を変更することはできないため、データをエクスポートし、新しい ID 値 (+10000) を設定してから、データを再度インポートする必要があると思います。

誰でも良い案が...

于 2011-05-18T15:51:08.983 に答える
1

問題の列に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オプションを使用してこれを行うようにしてください。このようにして発見された問題を修正します。

  • 最後に、マップテーブルを削除し、シングルユーザーフラグをクリアして、システムをオンラインに戻します。

ケーキ!(か何か。)

于 2011-05-18T17:49:13.030 に答える
1

私の提案は次のとおりです。

  1. テーブルへの書き込みを停止します。
  2. 新しい PK を使用してテーブルを新しいテーブルにコピーします。
  3. 古いテーブルの名前をバックアップ名に変更します。
  4. 新しいテーブルの名前を元のテーブル名に変更します。
  5. すべてのテーブルの行を数えて、作業を再確認してください。
  6. テーブルの使用を続行します。

事後に PK を変更するのは楽しくありません。

于 2011-05-18T16:16:08.943 に答える
1

PK フィールドの長さを延長する代わりに、別のフィールドを PK に追加することを検討してください。フィールドの長さを増やす場合と同様に、新しいフィールドを関連するテーブルにカスケードする必要がありますが、元の PK 値を保持できます。

于 2011-05-18T17:24:20.353 に答える
0

このアプローチを検討してください。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を追加して、外部キーを更新します。

于 2011-05-18T19:59:59.713 に答える