8

Oracle データベースには、名前を知らなくても、column_name と reference_column_name だけの外部キーがあります。この外部キーが存在する場合は削除する SQL スクリプトを作成したいので、次のコードを使用します。

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
end;

このスクリプトの出力は「anonymous block completed」なので成功ですが、ドロップ部分を追加すると:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
 if (fName != '') THEN
  alter table MY_TABLE_NAME drop constraint fName;
 end if;
end;

次に、これを取得します。

エラー レポート: ORA-06550: 行 9、列 5: PLS-00103: 次のいずれかを予期しているときに、シンボル "ALTER" が発生しました:

begin case declare exit for goto if loop mod null pragma raise return select update while with << close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe 06550. 00000 - "line %s, column %s:\n %s" *原因: 通常、PL/SQL コンパイル エラーです。*アクション:

では、ここで何が問題なのか誰か教えてもらえますか?

また、すべてを関数に入れようとしました:

declare
  function getFName return varchar2 is
    fName varchar2(255 char);
  begin
   SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';

   return fName;
  end;
begin
  if getFName() != '' then
   alter table all_events drop constraint getFName(); 
  end if;
end; 

結果は、ステートメント「alter table」によって引き起こされたのと同じエラーでした

これも役に立ちませんでした:

alter table all_events drop constraint
   (SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME');

出力は次のとおりです。

エラー レポート: SQL エラー: ORA-02250: 制約名 02250 がないか無効です。 00000 - "制約名がないか無効です" *原因: 制約名がないか無効です。*処置: 制約名に有効な識別子名を指定してください。

SQL サーバー (MS SQL) の場合、これを行うのは非常に簡単です。@ で変数を宣言して設定するだけで、その後はそのまま使用できます。オラクルでは、何が機能していないのかわかりません...

4

2 に答える 2

7

PL/SQL ブロックで DDL を直接実行できないことを除けば、元のバージョンはほとんど問題ありません。むしろ、次のようにラップする必要がありますEXECUTE IMMEDIATE

execute immediate 'alter table MY_TABLE_NAME drop constraint "' || fName || '"';

これは、コンパイル時に制約名がわかっている場合でも当てはまりますがfName、制約名ではなく、制約名を含む変数であるため、あなたの場合は二重に当てはまります。

また、これ:

if (fName != '') THEN

''オラクルでは を意味するため、有効/意味がありませんNULL。あなたは書くべきです

IF fName IS NOT NULL THEN

代わりは。

于 2012-01-25T18:56:57.910 に答える
3

これは、列に対して「R」と入力されたすべての制約を削除する方法です。

begin
    FOR rec IN (SELECT x.constraint_name fName FROM all_constraints x
        JOIN all_cons_columns c ON
        c.table_name = x.table_name AND c.constraint_name = x.constraint_name
        WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME')
    LOOP
        EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE_NAME DROP CONSTRAINT "' || rec.fName || '"';
    END LOOP;
end;
于 2013-02-03T09:54:40.163 に答える