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

19

我想动态删除一个Oracle约束,但事先并不知道它的名称,给定表名和列名。

我可以使用以下查询找到约束名称:

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
如果列上有多个约束条件,您可以使用 for i in (select) 循环 ... end loop 来捕获多个约束条件,但除此之外,我会采用我在下面发布的答案。 - Horus
2个回答

21

不行。SQL和DDL基本上是两种不同的语言。你的解决方案是正确的。


0

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

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接