删除PL / SQL循环中的约束

时间:2018-01-02 13:42:46

标签: 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 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表。

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

我不知道为什么我会得到丢失或无效的约束名称..感谢在这里帮助我。

3 个答案:

答案 0 :(得分:3)

您不能将绑定变量用于数据库对象的名称(或者通常用于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;
/

答案 1 :(得分:0)

为什么不使用此脚本生成DISABLE脚本?

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

答案 2 :(得分:0)

比原始尝试更简单(和工作):

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>