3

元の状態ではあまりきれいではなかった (Microsoft?) SQL データベースを継承しました。修正しようとしている非常に奇妙な点がまだいくつかあります。そのうちの 1 つは、ID エントリの一貫性がありません。

アカウント テーブルでは、各エントリに accountID と呼ばれる番号があり、これは他のいくつかのテーブル (メモ、機器など) で参照されます。問題は、(なんらかのランダムな理由で) 数値が約 -100000 から +2000000 の範囲で、エントリが約 7000 しかないことです。

他のテーブルの対応する番号を変更しながら、番号を付け直す良い方法はありますか? 私は自由に ColdFusion も持っているので、SQL で動作するもの、および/または受け入れるものは何でも受け入れます。

4

6 に答える 6

4

代理キーの場合、それらは無意味であることを意図しているため、実際にデータベースの整合性の問題があった場合 (適切に定義された外部キー制約がなかった場合など)、または ID がそのデータ型の最大値に近づいていない限り、私はそれらをそのままにして後を追うでしょう。より影響力のある他の簡単な成果。

于 2009-01-15T04:50:29.593 に答える
2

この場合、「どのように」よりも「なぜ」の方が適切な質問のように思えます。OPは、修正が必要な奇妙な問題があることを指摘していますが、それが問題である理由は述べていません。それは問題を引き起こしていますか?これらの数値を変更すると、どのようなプラスの影響がありますか? 最初にシステムをプログラムし、番号が現在の状態にある理由を正確に理解していない限り、このような変更を行うことは非常に危険です。

于 2009-01-15T19:36:39.540 に答える
1

これが金融アプリである場合、会計テーブルの数字をいじる前に、会計士 (または少なくともあなたの金融関係者) に相談します。勘定科目表は、財務の報告方法にとって非常に重要です。これらの ID には、理解できない意味がある場合があります。理由がない限り、誰も否定的な ID を入力しません。そもそもそれが否定的である理由を理解しない限り、私は決してそれを変えることはありません. 不必要な変更を加えることで、税務申告やその他のことを本当に台無しにする可能性があります。

于 2009-01-15T14:15:54.973 に答える
0

ColdFusion では、これは大変な作業ではありませんが、面倒なので注意が必要です。使用できる方法の 1 つは、データベースのスクリプトを作成してから、まったく新しい空のテーブル スキーマを生成することです。accountID を新しいデータベースの ID フィールドとして設定します。

次に、ColdFusion を使用して、古いアカウント データをすべて取得し、新しいデータベースに 1 つずつ挿入するクエリを作成します。行ごとに、新しいデータベースに新しい ID を割り当てさせます。各挿入の後、(@@IDENTITY または MAX(accountID) を使用して) 新しい ID を取得し、新しい ID と古い ID を一時テーブルに一緒に保存して、どの古い ID がどの新しい ID に属しているかを確認します。

次に、各子テーブルでこのプロセスを繰り返します。古い ID ごとに、その子エントリをプルし、新しい ID を使用してそれらを新しいデータベースに再挿入します。子テーブルの主キーに問題がない場合は、それらをそのまま挿入するか、重要でない場合はサーバーに新しいキーを割り当てさせることができます。

リレーションシップを一時的に無効にして新しい ID を適切に割り当てることもできますが、古いデータによって既に使用されている ID がエントリの 1 つに割り当てられている場合、競合が発生する可能性があります。

于 2009-01-15T04:50:09.033 に答える
0

アカウント テーブルに新しい ID 用の新しい列を作成し、関連する各テーブルに新しい列を作成して、新しい ID 列を参照します。

ALTER TABLE accounts
ADD new_accountID int IDENTITY

ALTER TABLE notes
ADD new_accountID int

ALTER TABLE equipment
ADD new_accountID int

次に、各参照テーブルの new_accountID 列を accounts テーブルにマップできます。

UPDATE notes
SET new_accountID = accounts.new_accountID
FROM accounts
INNER JOIN notes ON (notes.accountID = accounts.accountID)

UPDATE equipment
SET new_accountID = accounts.new_accountID
FROM accounts
INNER JOIN equipment ON (equipment.accountID = accounts.accountID)

この時点で、各テーブルには、古いキーを持つ accountID と、新しいキーを持つ new_accountID の両方があります。ここからはかなり簡単です。

  1. accountID のすべての外部キーを解除します。
  2. 各テーブルで、UPDATE [table] SET accountID = new_accountID.
  3. accountID の外部キーを再度追加します。
  4. 不要になったため、すべてのテーブルから new_accountID を削除します。
于 2009-01-15T13:37:37.937 に答える
0

おそらく、外部キーの関係を無効にして (一時的にオフラインにできる場合)、スクリプトを使用して主キーを更新できます。以前にこの更新スクリプトを使用して値を変更したことがありますが、このコードをカーソルで簡単にラップして、問題のキー値を 1 つずつ確認し、追跡している増分値に任意の値を更新できます。の。

ここでスクリプトを確認してください: http://vyaskn.tripod.com/sql_server_search_and_replace.htm

主キーを使用するテーブルのリストがあるだけの場合は、カーソル内で実行される一連の UPDATE ステートメントを設定でき、このスクリプトを使用する必要はありません (少し遅くなる可能性があります)。

ただし、これらの値が奇抜に見える理由を尋ねることは価値があります。このデータベースには値が常に追加および削除されていますか? 主キーの値は本当に恣意的なものですか、それともそうであるように見えますが、実際には意味がありますか? 私はすべて統合に賛成ですが、これらの値に目的がないことを確認する必要があります。

于 2009-01-15T04:46:26.200 に答える