制約の名前がわからない場合、Oracleで「非NULL」制約を削除するにはどうすればよいですか。


85

フィールドにNOTNULL制約があるデータベースがあり、この制約を削除したいと思います。複雑な要因は、この制約にはシステム定義の名前があり、その制約の名前は本番サーバー、統合サーバー、およびさまざまな開発者データベース間で異なることです。現在のプロセスは変更スクリプトをチェックインすることであり、自動化されたタスクがターゲットデータベースに対してsqlplusを介して適切なクエリを実行するため、sqlplusに直接送信できるソリューションをお勧めします。

私自身のデータベースでは、これを削除するSQLは次のようになります。

alter table MYTABLE drop constraint SYS_C0044566

all_constraintsビューをクエリすると、制約が表示されます。

select * from all_constraints where table_name = 'MYTABLE'

しかし、SEARCH_CONDITIONLONGデータ型を操作する方法や、名前を知った後でもルックアップされた制約を動的に削除する最善の方法がわかりません。

では、名前ではなく、制約に基づいてこの制約を削除できる変更スクリプトを作成するにはどうすればよいでしょうか。


編集:@Allanの答えは良いものですが、(Oracleの専門知識が不足しているため)システムで生成された名前を持つ可能性のある制約がそれに関連付けられて、名前を知らなくても制約。システム名の制約を論理的に削除するときに、その制約の名前を知らなくても済むようにする方法が常にあるというのは本当ですか?


3
好奇心を満たすために:NOT NULL制約は、制約の名前を知らなくても削除できるOracleの唯一の制約タイプです。制約の名前を知る必要がある他のすべての制約タイプ。
ジェフリーケンプ2012年

回答:


166
alter table MYTABLE modify (MYCOLUMN null);

Oracleでは、列にnull以外の制約が指定されている場合、null以外の制約が自動的に作成されます。同様に、nullを許可するように列が変更されると、それらは自動的に削除されます。

改訂された質問の明確化:この解決策は、「nullではない」列に対して作成された制約にのみ適用されます。名前を付けずに列定義で「主キー」またはチェック制約を指定すると、システムによって生成された制約の名前(および主キーのインデックス)が作成されます。そのような場合、それをドロップするには名前を知っている必要があります。「null以外」以外のすべての制約に名前を指定することで、シナリオを回避することをお勧めします。これらの制約の1つを一般的に削除する必要がある状況に陥った場合は、おそらくPL / SQLとデータ定義テーブルに頼る必要があります。


それは本当に良すぎるように思えますが、それは間違いなく私の現在のケースを処理し、明らかに単純です!オラクルで、制約名をシステムで生成できたのに、そのような制約名を回避するためにSQLを記述できなかったケースはありますか?
クリスファーマー

1
おかげで...not null制約は私のスキーマでこのように私に影響を与える可能性が高い唯一のシステム名の制約であることがわかりました。
クリスファーマー

16

試してみてください:

alter table <your table> modify <column name> null;

1

null許容にしたいフィールドが主キーの一部である場合、それはできないことを覚えておいてください。主キーにnullフィールドを含めることはできません。


1

使用されている制約を見つけるには、以下のコードを使用します。

-- Set the long data type for display purposes to 500000.

SET LONG 500000

-- Define a session scope variable.

VARIABLE output CLOB

-- Query the table definition through the <code>DBMS_METADATA</code> package.

SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual;

これは基本的に、参照されるテーブルがどのように作成されるかについてのcreateステートメントを示しています。テーブルがどのように作成されるかを知ることにより、すべてのテーブル制約を確認できます。

Michael McLaughlinのブログからの回答:http//michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/彼のデータベースデザインIクラスから。


0

異なる値を許可するために更新する必要があるカスタムチェック制約を回避しようとして、同じ問題に直面していました。問題は、ALL_CONSTRAINTSには、制約が適用されている列を判別する方法がないことです。私がそれを行うことができた方法は、代わりにALL_CONS_COLUMNSにクエリを実行し、次に各制約を名前で削除して再作成することです。

all_cons_columnsからconstraint_nameを選択します。ここでtable_name = [TABLE_NAME]およびcolumn_name = [COLUMN_NAME];


0

構造体を一時テーブルにコピーしたときにそのようなことが起こったので、notnullを削除しました。

DECLARE
   CURSOR cur_temp_not_null IS
        SELECT table_name, constraint_name  FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND  owner='myUSUARIO';

   V_sql VARCHAR2(200); 

BEGIN
  FOR c_not_null IN cur_temp_not_null
   LOOP
     v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name;
     EXECUTE IMMEDIATE  v_sql;     
  END LOOP;
END;

StackOverflowは英語のみのサイトです。ただし、StackOverflowenespañolがあります。私の編集を参照してください。
–help

0

テーブルの作成中に列STATUSの制約が名前なしで作成された場合、Oracleはそれにランダムな名前を割り当てます。残念ながら、制約を直接変更することはできません。

列STATUSにリンクされた名前のない制約を削除する手順

  1. STATUSフィールドを新しいフィールドSTATUS2に複製します
  2. STATUS2にCHECK制約を定義する
  3. データをSTATUSからSTATUS2に移行します
  4. ステータス列を削除します
  5. STATUS2の名前をSTATUSに変更します

    ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN'; ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED')); UPDATE MY_TABLE SET STATUS2 = STATUS; ALTER TABLE MY_TABLE DROP COLUMN STATUS; ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.