在Oracle ALTER语句中可以使用子查询吗?

问题描述:

给定一个表名和列名,我试图动态地删除一个Oracle约束,我不知道提前的名字。在Oracle ALTER语句中可以使用子查询吗?

我可以用这个查询找到约束名称:

SELECT CONSTRAINT_NAME 
FROM USER_CONS_COLUMNS 
WHERE TABLE_NAME = 'MyTable' AND 
COLUMN_NAME='MyColumn' AND POSITION IS NULL 

我首先想到的是使用子查询,但是,这并不在ORA-02250错误的工作和结果:

ALTER TABLE MyTable 
    DROP CONSTRAINT (
    SELECT CONSTRAINT_NAME 
    FROM USER_CONS_COLUMNS 
    WHERE TABLE_NAME = 'MyTable' AND 
    COLUMN_NAME='MyColumn' AND POSITION IS NULL) 

到目前为止,唯一的工作解决我有如下,但是感觉不必要的复杂:

DECLARE 
statement VARCHAR2(2000); 
constr_name VARCHAR2(30); 
BEGIN 
    SELECT CONSTRAINT_NAME INTO constr_name 
    FROM USER_CONS_COLUMNS 
    WHERE table_name = 'MyTable' AND 
    column_name = 'MyColumn' AND position is null; 
    statement := 'ALTER TABLE MyTable DROP CONSTRAINT '|| constr_name; 
    EXECUTE IMMEDIATE(statement); 
END; 
/

有没有一种方法可以像我最初的意图那样通过子查询来实现?如果没有,任何人都可以提出一个更简洁的方法来做到这一点?

+1

如果有在列多的限制,你可以为我做了(选择)环......结束循环,而是和抓倍数,但除此之外,我会与我下面发布的答案。 – Horus 2011-05-05 21:33:20

你不能。 SQL和DDL基本上是两种分离的语言。您的解决方案正确。

+1

谢谢你,荷鲁斯。 – 2011-05-06 13:15:32

要删除多个检查约束...

declare 
i number; 
begin 
for I in (select CONSTRAINT_NAME from USER_CONS_COLUMNS B where B.CONSTRAINT_NAME in (
select a.constraint_name from USER_CONSTRAINTS a where a.TABLE_NAME = 'MAHI' and a.CONSTRAINT_TYPE = 'C') 
AND B.COLUMN_NAME in ('EMP_NAME','EMP_SAL')) 
LOOP 
EXECUTE IMMEDIATE('alter table DIM_CHR_LOV DROP CONSTRAINT '|| I.CONSTRAINT_NAME); 
end LOOP; 
end; 

DECLARE 
    statement VARCHAR2(2000); 

    cursor foraneas is 
    SELECT cc.constraint_name as nombre_contraint, cc.table_name as nombre_tabla 
    from all_constraints c, all_cons_columns cc 
    where c.constraint_name = cc.constraint_name 
     and cc.table_name 'YourTableName' and cc.column_name = 'yourColumName'; 
BEGIN 

    for r_foranea in foraneas loop 
    statement := ' ALTER TABLE '||r_foranea.nombre_tabla||' drop constraint '|| r_foranea.nombre_contraint; 
    dbms_output.put_line(statement); 
    EXECUTE IMMEDIATE(statement); 
    end loop; 
END;