web-dev-qa-db-ja.com

存在しない制約は削除できず、作成もできません

本番データのコピーを使用して一部の移行スクリプト(スクリプトは開発データで正常に実行されます)をテストしているときに、奇妙な状況が見つかりました。 CONSTRAINTが変更されたため、DROP + ADDコマンドを発行します。

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;

ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
    CONTROL_ID,
    CALLE_AYTO_DUPL
)
ENABLE;

DROPコマンドは正常に機能しましたが、ADDコマンドは失敗しました。今、私は悪循環に陥っています。制約が存在しないため、ドロップできません(最初のドロップは期待どおりに機能しました)。

ORA-02443:制約を削除できません-存在しない制約

そして、名前がすでに存在しているので作成できません:

ORA-00955:名前は既存のオブジェクトですでに使用されています

私はタイプする A_DUP_CALLE_UK1 SQL開発者のSearchボックスに入力すると...あります!所有者、テーブル名、テーブルスケープ...すべてが一致します。同じ名前の別のオブジェクトではありませんis元の制約です。表は制約の詳細に表示されますが、制約は表の詳細には表示されません。

私の質問:

  • これの説明は何ですか?
  • ライブサーバーで実際のアップグレードを行ったときにそれが起こらないようにするにはどうすればよいですか?

(サーバーは10g XEで、タグを作成するのに十分な評判がありません。)

16

おそらく私はマリアンが正しいと思いますが、これは同じ名前を持つ一意のインデックスと制約によって引き起こされます。例:

create table t( k1 integer, k2 integer, 
                constraint u1 unique(k1,k2) using index(create unique index u1 on t(k1,k2)),
                constraint u2 unique(k2,k1) using index u1);

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

alter table t drop constraint u1;

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

通常、一意の制約を追加すると、同じ名前の一意のインデックスが作成されますが、インデックスと制約は同じものではありません。 all_indexesを調べて、A_DUP_CALLE_UK1というインデックスがあるかどうかを確認し、ドロップする前に、他の何かによって使用されているかどうかを確認してください。

非常に奇妙なようです。

以下を実行できます。

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

オラクルであるどのようなオブジェクトが不満を持っているかを確認します。次に、そのための適切なDROPステートメントを実行できます。

他に考えられる唯一のことは、DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTSを使用してテーブルを完全に削除し、そのテーブルに属するすべてのものを削除してから、完全に再作成することです。

テーブルに価値のあるデータが含まれている場合は、その前にバックアップを作成できます。

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

テーブルを再作成したら、次のことができます

INSERT INTO A_DUP_CALLE (col1, col2, col3) 
SELECT col1, col2, col3
FROM old_data

データを復元します。

私は数分前に同じ問題を抱えていました...そして私は説明を見つけました。

Oracleは、主キーを作成することにより、「UNIQUE」部分を制御する制約とインデックスの2つのオブジェクトを作成します。

制約を削除すると、同じ名前のインデックスを使用してインデックスがそこに残ります。

alter table t drop constraint u1;

制約のみを削除します。インデックスを削除するには、実行する必要があります

drop index u1;

これでうまくいくはずです。または、次のコマンドを使用して、これらの両方のコマンドを同時に実行することもできます

alter table t drop constraint u1 including indexes;
5

主キー制約にはインデックスが付属しています。制約は削除しますが、索引は削除しません。小切手:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

あなたはOBJECT_TYPEINDEXです。

だから両方を行う:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;
1
gavenkoa

これを行う

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

それが動作します。

画像: enter image description here

1
Sachin