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

Loop DELETE unnamed foreign key from a table

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

table 的定义如下:

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)
);

/

我正在寻找一种工具,它允许我在 table 中检索外键的名称并删除它们以便使用 [=15= 添加到外键 on delete cascade 语句]声明如下:

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;
/

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

但是这个return我出现了以下错误:

Report error - ORA-06550: row 8, column 36: PLS-00201: identifier 'TABLE_NAME' must be declared ORA-06550: row 7, column 5: PL/SQL: Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error.

有人知道如何解决这个问题吗?

编辑:我需要动态检索这些名称,这样如果我将脚本交给我的朋友,他也可以这样做

如果没有明确提供,默认情况下每个约束都有名称,使用 \d foo\d+ foo 其中 fooschema.tableName 以显示 table 结构和所有约束及其名称

您的查询中没有 table_name。或者 select 它:

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;
/

您需要在 SELECT 列表中包含 user_constraints 数据字典视图的 table_name 列,并为游标添加限定符 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