2011-09-27 18 views
12

テーブルに新しい行を作成しようとしています。テーブルには2つの制約があります.1つはキーフィールド(DB_ID)にあり、もう1つはフィールドENVのいくつかの値に制約されています。私は挿入を行うと、私は挿入しようとしている、まだ私はこのエラーを取得してい分野の一つとして、キーフィールドが含まれていません。挿入時のユニークな制約違反:なぜですか? (Oracle)

unique constraint (N390.PK_DB_ID) violated 

はここでエラーが発生しSQLです:

insert into cmdb_db 
    (narrative_name, db_name, db_type, schema, node, env, server_id, state, path) 
values 
    ('Test Database', 'DB', 'TYPE', 'SCH', '', 'SB01', 381, 'TEST', '') 

私は、手動で行を挿入すると、Oracleがすでに使用中のDB_IDを割り当てようとしている可能性があります。このデータベースのデータは、何らかの形で本番データベースから復元/移動されましたが、どのように行われたかについての詳細はわかりません。

どのような考えですか?

答えて

34

は、おそらく、その値は表に定義挿入トリガ前行レベルによって移入されています。そのトリガーは、おそらくシーケンスから値を選択しています。

データは本番データベースから(おそらく最近に)移動されたので、データをコピーしたときにシーケンスも変更されなかったことになります。私はシーケンスがエラーにつながるテーブルに現在ある最大DB_IDよりもはるかに低い値を生成していると推測します。

あなたは、使用されているシーケンスを決定するためのトリガーを見て、

SELECT <<sequence name>>.nextval 
    FROM dual 

をやって、私は疑いがあるとして、場合

SELECT MAX(db_id) 
    FROM cmdb_db 

にそれを比較することにより、シーケンスを、この疑惑を確認することができデータベースにすでに存在する値を生成している場合は、未使用の値が生成されるまでシーケンスをインクリメントしたり、INCREMENTを非常に大きな値に設定したり、nextvalを1回取得したり、INCREMENTを1に戻す。

+9

+1わかりやすい推測 – APC

1

主キーフィールドDB_IDに値を指定していないようです。それが主キーの場合は、その列に固有の値を指定する必要があります。それを提供しない唯一の方法は、データベースのトリガーを作成することです(挿入時に、シーケンスから派生した値を提供する)。

これが別のデータベースからの復元であり、この新しいインスタンスにシーケンスがある場合、値を再利用しようとしている可能性があります。古いデータに1〜1000のユニークキーがあり、現在のシーケンスが500である場合は、すでに存在する値が生成されます。このテーブルのシーケンスが存在し、そのテーブルを使用しようとしている場合は、テーブルの値をシーケンスの現在の値と照合する必要があります。

あなたは、あなたのDB内の既存の主キーを複製しているようにあなたの誤差が見え

+0

私のデータベースには、新しい行が挿入されたときにキーが自動的に生成されるという情報があります。そのため、DB_IDに値を指定しない理由があります。さらに、データベース内の類似した他のテーブルに対しても同様の手法が働きます。自動的に生成されたIDキーがあります。 – Sean

+0

新しい環境に必要なトリガー/シーケンスが存在するかどうかをデータ辞書に照会できますか?おそらくすべてが古い環境からもたらされたわけではありません。 –

1

(それはもちろん存在する場合)シーケンスの現在の値を見るためにSEQUENCE_NAME.CURRVALを使用することができます。 IDENTITYキーワードのようなものを使用して、独自の主キーを実装するようにsqlコードを変更する必要があります。もしDB_ID列の値を提供していないので

CREATE TABLE [DB] (
    [DBId] bigint NOT NULL IDENTITY, 
    ... 

    CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC), 

); 
+1

IDENTITYは、Oracleでは有効なキーワードではありません。 –

+0

これは、Oracle –

+1

の無効な文です。あなたは正しいです。私のソリューションはSQLではなくOracleで動作します。 OracleでSQLのアイデンティティーを複製したい場合は、Sequences [リンク](http://www.techonthenet.com/oracle/sequences.php)を使用することをお勧めします。@ Justin_Caveは彼の答えでうまく実装されています。 –

関連する問題