在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;
/
有没有一种方法可以像我最初的意图那样通过子查询来实现?如果没有,任何人都可以提出一个更简洁的方法来做到这一点?
答
你不能。 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;
如果有在列多的限制,你可以为我做了(选择)环......结束循环,而是和抓倍数,但除此之外,我会与我下面发布的答案。 – Horus 2011-05-05 21:33:20