Oracle 在PL/SQL循环中删除约束

Oracle 在PL/SQL循环中删除约束,oracle,plsql,Oracle,Plsql,当我试图从hr.employees表中禁用约束时,出现以下错误 错误: Error report - ORA-02250: missing or invalid constraint name ORA-06512: at line 14 02250. 00000 - "missing or invalid constraint name" *Cause: The constraint name is missing or invalid. *Action: Specify a val

当我试图从hr.employees表中禁用约束时,出现以下错误

错误:

Error report -
ORA-02250: missing or invalid constraint name
ORA-06512: at line 14
02250. 00000 -  "missing or invalid constraint name"
*Cause:    The constraint name is missing or invalid.
*Action:   Specify a valid identifier name for the constraint name.
下面是代码

DECLARE 
    CURSOR C1 IS SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME ='EMPLOYEES';
    v_con_name VARCHAR2(20);
    SQL_STATMENT  VARCHAR2(100);

BEGIN
    SQL_STATMENT := 'ALTER TABLE HR.EMPLOYEES DISABLE CONSTRAINT :A';
    OPEN C1;
    LOOP
        FETCH C1 INTO v_con_name;
        EXIT WHEN C1%NOTFOUND;
        EXECUTE IMMEDIATE SQL_STATMENT USING v_con_name;
        DBMS_OUTPUT.PUT_LINE(v_con_name);
    END LOOP;
    CLOSE C1;
END;
/   
当我评论下面这行时

EXECUTE IMMEDIATE SQL_STATMENT USING v_con_name;
脚本成功执行并提供以下结果

EMP_LAST_NAME_NN
EMP_EMAIL_NN
EMP_HIRE_DATE_NN
EMP_JOB_NN
EMP_SALARY_MIN
EMP_EMAIL_UK
EMP_EMP_ID_PK
EMP_DEPT_FK
EMP_JOB_FK
EMP_MANAGER_FK


PL/SQL procedure successfully completed.
因此,我知道游标构造正在获取所需的约束名称,并且在这个plsql块之外,我可以通过禁用这些约束成功地更改employees表

请注意,我已以HR模式登录Oracle 11g R2 XE数据库


我不确定为什么会得到缺少的或无效的约束名称。。感谢您的帮助。

为什么不使用此脚本生成禁用脚本

SELECT 'ALTER TABLE '||OWNER||'.'||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';' STMNT
FROM DBA_CONSTRAINTS
WHERE
R_CONSTRAINT_NAME IN
(SELECT CONSTRAINT_NAME
FROM DBA_CONSTRAINTS
WHERE CONSTRAINT_TYPE IN ('P','U')
AND OWNER = 'HR'
AND TABLE_NAME IN
(
'EMPLOYEES'
));

为什么不使用此脚本生成禁用脚本

SELECT 'ALTER TABLE '||OWNER||'.'||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';' STMNT
FROM DBA_CONSTRAINTS
WHERE
R_CONSTRAINT_NAME IN
(SELECT CONSTRAINT_NAME
FROM DBA_CONSTRAINTS
WHERE CONSTRAINT_TYPE IN ('P','U')
AND OWNER = 'HR'
AND TABLE_NAME IN
(
'EMPLOYEES'
));

不能将绑定变量用于数据库对象的名称(或通常用于DDL)。您需要通过连接名称来构建整个ALTER语句。试着这样做:

declare
    k_tablename constant user_constraints.table_name%type := 'EMPLOYEES';
begin
    for r in (
        select constraint_name
             , 'alter table ' || c.table_name || ' disable constraint ' || c.constraint_name as sql_statement
        from   user_constraints c
        where  table_name = k_tablename
    )
    loop
        execute immediate r.sql_statement;

        dbms_output.put_line('Disabled constraint ' || k_tablename || '.' || r.constraint_name);
    end loop;

end;
/

不能将绑定变量用于数据库对象的名称(或通常用于DDL)。您需要通过连接名称来构建整个ALTER语句。试着这样做:

declare
    k_tablename constant user_constraints.table_name%type := 'EMPLOYEES';
begin
    for r in (
        select constraint_name
             , 'alter table ' || c.table_name || ' disable constraint ' || c.constraint_name as sql_statement
        from   user_constraints c
        where  table_name = k_tablename
    )
    loop
        execute immediate r.sql_statement;

        dbms_output.put_line('Disabled constraint ' || k_tablename || '.' || r.constraint_name);
    end loop;

end;
/
比最初的尝试稍微简单一些(&working):

SQL> create table test (id number constraint pk_test primary key,
  2    ime varchar2(20) constraint ch_ime check (ime in ('little', 'foot')));

Table created.

SQL>
SQL> begin
  2    for c1 in (select table_name, constraint_name
  3               from user_constraints
  4               where table_name = 'TEST')
  5    loop
  6      execute immediate 'alter table ' || c1.table_name ||
  7                        ' disable constraint ' || c1.constraint_name;
  8    end loop;
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL> select constraint_name, status From user_constraints where table_name = 'TEST';

CONSTRAINT_NAME                STATUS
------------------------------ --------
CH_IME                         DISABLED
PK_TEST                        DISABLED

SQL>
比最初的尝试稍微简单一些(&working):

SQL> create table test (id number constraint pk_test primary key,
  2    ime varchar2(20) constraint ch_ime check (ime in ('little', 'foot')));

Table created.

SQL>
SQL> begin
  2    for c1 in (select table_name, constraint_name
  3               from user_constraints
  4               where table_name = 'TEST')
  5    loop
  6      execute immediate 'alter table ' || c1.table_name ||
  7                        ' disable constraint ' || c1.constraint_name;
  8    end loop;
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL> select constraint_name, status From user_constraints where table_name = 'TEST';

CONSTRAINT_NAME                STATUS
------------------------------ --------
CH_IME                         DISABLED
PK_TEST                        DISABLED

SQL>

感谢它的工作,我明白我不能在绑定变量中使用db对象!感谢它的工作,我明白我不能在绑定变量中使用db对象!