2012-03-14 14 views
0

私は巨大なデータベース(SQL Server)をクリーニングしており、更新ステートメントがテーブルのPKに違反している場合に行を削除できるかどうかを知りたいと思っています。スクリプトを終了せずにSQLスクリプトで主キー違反を処理するにはどうすればよいですか?

私はこのような何かしたい:

UPDATE EMODCONCT SET CODPERLET = '2003' WHERE CODPERLET = '2003BI' 
IF "UPDATE VIOLATES PK OF EMODCONCT" THEN 
DELETE FROM EMODCONCT WHERE CODPERLET = '2003BI' 
END 
<DON'T SHOW ANY ERROR AND CONTINUE THE EXECUTION OF THE SCRIPT> 

は、この種のエラー、エラーで中断することなく実行を継続するためのコマンドを検出するために、任意のフラグがありますか?

ありがとうございました!

+0

テーブル間のPK/FK関係を正しく設定していれば、pkDataがプライマリテーブルで利用可能でない限り更新することはできません。 – Kaf

+3

だから、PKの値を変更したいのですが、その新しい値が実際に重複している場合は結果を削除してから続行しますか?まず最初に複製するすべての値を最初に削除しないでください。 – Lamak

答えて

1

エラーが発生しないように、まずテーブルに値が含まれているかどうかを確認しないでください。

IF EXISTS(SELECT NULL FROM EMODCONCT WHERE CODPERLET = @newId) 
BEGIN 
    DELETE FROM EMODCONCT WHERE CODPERLET = @oldId 
END 
ELSE 
BEGIN 
    UPDATE EMODCONCT 
     SET CODPERLET = @newId 
    WHERE CODPERLET = @oldId 
END 
+0

原因私は36テーブルのように更新しており、すべてのテーブルの主キーの組み合わせが異なります。 "CODPERLET"だけが共通のPKです。この場合、すべてのテーブルに対して差分検証を行う必要があり、高速なソリューションを探していました。とにかくありがとう! – Sawd

+0

これはあなたの例から書いてほしいコードとほぼ同じです。相違点は、エラーが発生するのを待ってから、それを処理することです。私は、エラーが発生する前の状況を検出し、まったく同じ方法でそれを処理しています。あなたはおそらくtry catchでこの問題を解決するより多くのコードを書くでしょう。 – cadrell0

+0

キャッチしよう!どうやって忘れてしまったの?私はT-SQLでこれを使ったことはありませんでしたが、試してみましょう。ありがとう。 – Sawd

1

あなたのデータ要素名とサンプルデータは私に慣れていないので、私はそれらを変更します:)

のはOrdersテーブルの主キーが(product_name, customer_name)の化合物であるとしましょう。行は、以下の提案のためにあります。

Colm orders freezer 
Pete orders toaster 
Ravi orders freezer 
Ravi orders toaster 

要件:更新は、トースターの注文に冷凍庫のためにすべての注文を変更するが、これが原因となる場合はPK違反は、違反した行を削除します。

したがって
Colm orders freezer -> (row is altered to) Colm ordered toaster 
Pete orders toaster -> (row is unaffected) Pete ordered toaster 
Ravi orders freezer -> (row is deleted) 
Ravi orders toaster -> (row is deleted) 

  1. は、顧客が両方冷凍庫トースターの受注を持っている行を削除します。
  2. 顧客がフリーザーがトースターの注文となる注文を受けた行を変更します。

p.s.これはかなり異例のアップデートのように聞こえるので、デザイナーとスペックを再確認して、その意図が明確であることを確認してください。

+1

誰もがdownvoteを説明できますか?明らかに私はアナロジーを使用していますが(言及したように)、私の分析は間違っていますか? – onedaywhen

2

TRY CATCHブロックの使用はどうですか?

BEGIN TRY 
    UPDATE EMODCONCT SET CODPERLET = '2003' WHERE CODPERLET = '2003BI' 
END TRY 
BEGIN CATCH 
    IF ERROR_NUMBER() = 2627 -- Violates Primary Key 
    DELETE FROM EMODCONCT WHERE CODPERLET = '2003BI' 
END CATCH 
関連する問題