2017-05-30 22 views
-1

3つの列を持つSQL Serverテーブルがあり、最初の2つの列が主キーです。私は大量の最後の2つの列を更新するストアドプロシージャを書いているし、プライマリキーの違反がない限り、正常に動作しますが、プライマリキーの違反があるとエラーをスローして実行を停止します。複合キーを使用したSQL Serverテーブルの更新

プライマリキー違反がない限り、行を無視してレコードを更新するにはどうしたらよいですか?

この問題にアプローチするより良い方法はありますか?私は単にcolumn2 = somevalueとcolumn3 =いくつかの値で単純な更新をしています。 SQL Serverでの

+0

MSQLは何を表していますか? mSQL?またはこれはMySQLのタイプミスですか?それともMicrosoft SQL Serverですか?あなたが探しているのは、大語彙でupsertと呼ばれ、構文はDBMSごとに異なります。 –

+0

申し訳ありませんが、私はMicrosoft SQLを意味していました。私はその略語がMicrosoft Sqlのために何であるか分かりません – Tex

+0

Microsoftは2つのDBMS(AFAIK)を持っています:MS AccessとSQL Server。私はあなたがSQL Serverを意味すると思いますか? –

答えて

0

あなたは(すなわち、挿入または更新)アップサートするMERGEを使用したい:

MERGE mytable 
USING (SELECT 1 as key1, 2 as key2, 3 as col1, 4 as col2) AS src 
    ON (mytable.key1 = src.key1 AND mytable.key2 = src.key2) 
WHEN MATCHED THEN 
    UPDATE SET col1 = src.col1, col2 = src.col2 
WHEN NOT MATCHED THEN 
    INSERT (key1, key2, col1, col2) VALUES (src.key1, src.key2, src.col1, src.col2); 
+0

ありがとうございます。私は明日それを試み、あなたに知らせるでしょう。なぜ私は新しいレコードを挿入しようとしているのではなく、すでに存在する場合にのみ更新するように挿入を使用している理由を正確にはわかりません。 – Tex

+0

申し訳ありませんが、あなたは正しいです。私はあなたの質問を誤解しました。更新のみですが、*主キー*を更新しています。だからこの答えを無視してください。私は後でそれを削除するつもりです。あなたがしていることについて:*決して*プライマリキーを更新しないでください。これは、その存続期間の行を識別するためのものです。それを更新する必要があると思われる場合、これは悪いデータベース設計の可能性が高いです。 –

0

あなたの質問で、本質的には何も問題はむしろ大声で抗議にもかかわらず、ありません。あなたの質問は混乱しています。それは大きなノーノです。だから、あなたの問題を実証し、有用な提案を得るためには、あなたの問題を示すスクリプトが一般的には最良の方法です。

あなたの質問に対する短い答えは - できません。ステートメントは全体として成功するか失敗するか。個々の行を個別に更新して特定のエラーを無視したい場合は、それを行うためにtsqlを作成する必要があります。

抗議にもかかわらず、主キーの一部である列を更新する必要がある状況があります。珍しいことですが、非常に珍しいですが、tsqlに関する絶対的な声明にも注意する必要があります。珍しいことをするときは、スキーマ(およびあなたのアプローチ)を見直さなければなりません。あなたの目標を達成するためのより良い方法がある可能性が高いからです。

この場合、はあなたが達成しようとしていることを本当に考えてください。特定の方法で行のセットを更新したい場合は、文が失敗します。つまり、どこかに欠陥があることを意味します。通常、このエラーは、更新ロジックが正しくないことを意味します。おそらく、正確ではないデータについて何かを想定しているでしょうか?遠くから知ることは不可能です。エラーメッセージには、競合の原因となった値のセットが表示されます。そのため、調査するのに十分な情報が得られるはずです。別のツールとして、提案された更新を示すselect文を記述し、エラーメッセージの値を探します。例えば。

set nocount on; 
create table #x (a smallint not null, b smallint not null, c varchar(10) not null, constraint xx primary key(a, b)); 

insert #x (a, b, c) values (1, 1, 'test'), (1, 2, 'zork'); 
select * from #x; 

update #x set b = 2, c = 'dork'; 

select a, b, c, cast(2 as smallint) as new_b, 'dork' as new_c 
from #x 
order by a, new_b; 

drop table #x; 
関連する問題