2011-05-05 93 views
11

給定一個表名和列名,我試圖動態地刪除一個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

回答

16

你不能。 SQL和DDL基本上是兩種分離的語言。您的解決方案正確。

+1

謝謝你,荷魯斯。 – 2011-05-06 13:15:32

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; 
-2
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; 
相關問題