2012-01-26 61 views
4
declare 
fName varchar2(255 char); 
begin 
SELECT x.constraint_name into fName FROM all_constraints x 
JOIN all_cons_columns c ON 
c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME'; 
if fName is not null THEN 
    execute immediate 'alter table MY_TABLE_NAME drop constraint ' || fName; 
end if; 

SELECT x.constraint_name into fName FROM all_constraints x 
JOIN all_cons_columns c ON 
c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
WHERE x.table_name = 'OTHER_MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='OTHER_MY_COLUMN_NAME'; 
if fName is not null THEN 
    execute immediate 'alter table OTHER_MY_TABLE_NAME drop constraint ' || fName; 
end if; 
end; 

嗨@, 我使用上面的代碼來獲取我想要刪除的約束的名稱,並且我有很多這樣的選擇,並且如果 - > drop語句。 我的問題是,如果其中一個選項沒有返回任何異常,則拋出異常。我可以捕獲異常,但是在「begin end」結構的末尾(所有select語句之後,所以其餘的drop將永遠不會被執行)。我該如何安排這一點,如果選擇什麼都不返回,我只是不想丟棄任何東西:)oracle select into變量時選擇什麼都不返回?

如果有另一種方式來定義一個變量並從select中填充它而不拋出異常,不管是否返回的名稱爲空或不是,我更喜歡它:)(現在我只是讓這個選擇進入工作狀態,除了選擇無返回值:))

回答

6

使用多個開始/異常/結束塊:

declare 
fName varchar2(255 char); 
begin 
begin 
    SELECT x.constraint_name into fName FROM all_constraints x 
    JOIN all_cons_columns c ON 
    c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
    WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME'; 
exception 
    when no_data_found then 
    fName := null; 
end; 

if fName is not null THEN 
    execute immediate 'alter table MY_TABLE_NAME drop constraint ' || fName; 
end if; 

begin  
SELECT x.constraint_name into fName FROM all_constraints x 
JOIN all_cons_columns c ON 
c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
WHERE x.table_name = 'OTHER_MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='OTHER_MY_COLUMN_NAME'; 
exception 
    when no_data_found then 
    fName := null; 
end; 

if fName is not null THEN 
    execute immediate 'alter table OTHER_MY_TABLE_NAME drop constraint ' || fName; 
end if; 
end; 
5

使用本地程序:

declare 

    procedure drop_constraint(i_table_name in varchar2, i_column_name in varchar2) 
    is 
    l_constr_name varchar2(255 char); 
    begin 
    SELECT x.constraint_name into fName FROM all_constraints x 
    JOIN all_cons_columns c ON c.table_name = x.table_name AND c.constraint_name = x.constraint_name 
    WHERE x.table_name = i_table_name AND x.constraint_type = 'R' AND c.column_name = i_column_name; 

    execute immediate 'alter table ' || i_table_name || ' drop constraint ' || l_constr_name; 

    exception 
    when NO_DATA_FOUND then 
     null; -- ignore or print message 
    end drop_constraint; 

begin 
    drop_constraint('MY_TABLE_NAME', 'MY_COLUMN_NAME'); 
    drop_constraint('OTHER_TABLE_NAME', 'OTHER_COLUMN_NAME'); 
end; 
/