从表中循环删除未命名的外键

时间:2019-07-13 10:17:07

标签: oracle plsql dynamic-sql

我想删除一些外键,但是不幸的是我没有命名该约束(并且我不能为自己的选择编辑该定义)。

该表的定义如下:

CREATE TABLE Disegnare(
        CF char(16),
        codCD int,

    --chiave primaria
    PRIMARY KEY(CF, codCD),

    --chiave esterna verso Persona
    FOREIGN KEY (CF) references Persona (CF),

    --chiave esterna verso class diagram
    FOREIGN KEY (codCD) references ClassDiagram (codCD)
);

/

我一直在寻找一种工具,该工具允许我检索表中的外键名称并删除它们,以便使用如下的on delete cascade语句将其添加到该外键alter table语句中:

ALTER TABLE Disegnare ADD CONSTRAINT fk_cf FOREIGN KEY (cf) REFERENCES Persona(cf) ON DELETE CASCADE;
ALTER TABLE Disegnare ADD CONSTRAINT fk_codcd FOREIGN KEY (codcd) REFERENCES 
ClassDiagram(codCd) ON DELETE CASCADE;

,所以我尝试了以下操作:

BEGIN
  FOR c IN
  (select constraint_name
   from user_constraints 
   where table_name = 'DISEGNARE' and constraint_type = 'R')
  LOOP
    dbms_utility.exec_ddl_statement
        ('alter table "'||table_name||'" drop constraint "'||constraint_name||'";');
  END LOOP;
END;
/

(请注意,表Disegnare有两个外键,因此我需要删除它们)

但这会返回以下错误:

  

报告错误-   ORA-06550:第8行,第36列:   PLS-00201:必须声明标识符“ TABLE_NAME”   ORA-06550:第7行,第5列:   PL / SQL:语句被忽略   06550。00000-“%s行,%s列:\ n%s”   *原因:通常是PL / SQL编译错误。

有人有解决此问题的想法吗?

编辑:我需要动态地检索该名称,以便将脚本交给我的一个朋友,他也可以这样做

3 个答案:

答案 0 :(得分:0)

如果没有明确提供,则每个约束默认都有名称,请使用\d foo\d+ foo,其中fooschema.tableName来显示表结构和所有约束及其名称< / p>

答案 1 :(得分:0)

您的查询中没有table_name。要么选择它:

BEGIN
  FOR c IN
  (select table_name, -- Here!
          constraint_name
   from user_constraints 
   where table_name = 'DISEGNARE' and constraint_type = 'R')
  LOOP
    dbms_utility.exec_ddl_statement
        ('alter table "'||table_name||'" drop constraint "'||constraint_name||'";');
  END LOOP;
END;
/

或者,由于您已将其硬编码在where子句中,因此也只需在alter语句中进行硬编码:

BEGIN
  FOR c IN
  (select constraint_name
   from user_constraints 
   where table_name = 'DISEGNARE' and constraint_type = 'R')
  LOOP
    dbms_utility.exec_ddl_statement
        ('alter table "DISEGNARE" drop constraint "'||constraint_name||'";');
    -- Here -----------^
  END LOOP;
END;
/

答案 2 :(得分:0)

您需要在table_name列表中包含user_constraints数据字典视图的SELECT列,并为光标添加限定符c.

BEGIN
  FOR c IN
  (select *
   from user_constraints 
   where table_name = 'DISEGNARE' and constraint_type = 'R')
  LOOP
    execute immediate 
    'alter table '||c.table_name||' drop constraint '||c.constraint_name;
  END LOOP;
END;
/

Demo