2016-02-02 94 views
2

我使用的是Oracle 12c和我不感興趣,而滴速我的表「大陸」中不存在的情況下有一個錯誤。DROP TABLE如果在甲骨文存在(如果不存在)

我這樣做

set echo on 
set serveroutput on 
alter session set current_schema=WORK_ODI; 
set verify off 
set pause off 

begin 
    execute immediate 'drop table continent'; 
    exception when others then null; 
end; 

這個腳本是工作,我很好。我使用這個腳本也:

declare 
    c int; 
begin 
    select count(*) into c from user_tables where table_name = upper('continent'); 
    if c = 1 then 
     execute immediate 'drop table continent'; 
    end if; 
end; 

兩個腳本的工作很好,但我的老闆要像IF EXIT。任何人都可以幫助我。在這種情況下如何使用IF EXIT?

+4

你確定他/他不想'如果存在'嗎? –

+1

如果你的老闆真的堅持關鍵字'EXIST',試試這個:'select count(*)into user_tables where EXIST(從user_tables中選擇null where table_name = upper('continent'));':-) –

+0

你可以寫有各自的行爲,自己的函數'drop_table_if_exists'。 – Dmitry

回答

-1

我有一個類似的問題 - 我需要找到一種方法如何重複DDL腳本而無需修改它們。成像以下腳本:

create table tab1(...); 

create table tab2(...); 

create table tab3{...}; /* <--- this one fails*/ 

create table tab4(...); 

所以現在我們有以下的情況:表「TAB1」和「TAB2」已成功創建「TAB3」和「TAB4」丟失。 因此,在修改「tab3」表的語句之後,我們必須註釋掉「tab1」和「tab2」的創建語句 - 處理包含許多DDL和許多錯誤的大型SQL腳本時可能會非常煩人。

所以我想出了下面的過程,它允許重新運行DDL語句:

create or replace procedure re_run_ddl (p_sql in varchar2) 
AUTHID CURRENT_USER 
as 
    l_line  varchar2(500) default rpad('-',20,'-'); 
    l_cr   varchar2(2)  default chr(10); 
    l_footer  varchar2(500) default l_cr||rpad('*',20,'*'); 
    l_ignore_txt varchar2(200) default 'IGNORING --> '; 
    ORA_00955 EXCEPTION; 
    ORA_01430 EXCEPTION; 
    ORA_02260 EXCEPTION; 
    ORA_01408 EXCEPTION; 
    ORA_00942 EXCEPTION; 
    ORA_02275 EXCEPTION; 
    ORA_01418 EXCEPTION; 
    ORA_02443 EXCEPTION; 
    ORA_01442 EXCEPTION; 
    ORA_01434 EXCEPTION; 
    ORA_01543 EXCEPTION; 
    ORA_00904 EXCEPTION; 
    ORA_02261 EXCEPTION; 
    ORA_04043 EXCEPTION; 
    ORA_02289 EXCEPTION; 
    PRAGMA EXCEPTION_INIT(ORA_00955, -00955); --ORA-00955: name is already used by an existing object 
    PRAGMA EXCEPTION_INIT(ORA_01430, -01430); --ORA-01430: column being added already exists in table 
    PRAGMA EXCEPTION_INIT(ORA_02260, -02260); --ORA-02260: table can have only one primary key 
    PRAGMA EXCEPTION_INIT(ORA_01408, -01408); --ORA-01408: such column list already indexed 
    PRAGMA EXCEPTION_INIT(ORA_00942, -00942); --ORA-00942: table or view does not exist 
    PRAGMA EXCEPTION_INIT(ORA_02275, -02275); --ORA-02275: such a referential constraint already exists in the table 
    PRAGMA EXCEPTION_INIT(ORA_01418, -01418); --ORA-01418: specified index does not exist 
    PRAGMA EXCEPTION_INIT(ORA_02443, -02443); --ORA-02443: Cannot drop constraint - nonexistent constraint 
    PRAGMA EXCEPTION_INIT(ORA_01442, -01442); --ORA-01442: column to be modified to NOT NULL is already NOT NULL 
    PRAGMA EXCEPTION_INIT(ORA_01434, -01434); --ORA-01434: private synonym to be dropped does not exist 
    PRAGMA EXCEPTION_INIT(ORA_01543, -01543); --ORA-01543: tablespace '<TBS_NAME>' already exists 
    PRAGMA EXCEPTION_INIT(ORA_00904, -00904); --ORA-00904: "%s: invalid identifier" 
    PRAGMA EXCEPTION_INIT(ORA_02261, -02261); --ORA-02261: "such unique or primary key already exists in the table" 
    PRAGMA EXCEPTION_INIT(ORA_04043, -04043); --ORA-04043: object %s does not exist 
    PRAGMA EXCEPTION_INIT(ORA_02289, -02289); --ORA-02289: sequence does not exist 
    procedure p(
     p_str  in varchar2 
     ,p_maxlength in int  default 120 
) 
    is 
    i  int := 1; 
    begin 
    dbms_output.enable(NULL); 

    while ((length(substr(p_str,i,p_maxlength))) = p_maxlength) loop 
     dbms_output.put_line(substr(p_str,i,p_maxlength)); 
     i := i + p_maxlength; 
    end loop; 

    dbms_output.put_line(substr(p_str,i,p_maxlength)); 
    end p; 
begin 

    p('EXEC:'||l_cr||l_line||l_cr||p_sql||l_cr||l_line); 

    execute immediate p_sql; 

    p('done.'); 

exception 
    when ORA_00955 or ORA_01430 or ORA_02260 or ORA_01408 or ORA_00942 
     or ORA_02275 or ORA_01418 or ORA_02443 or ORA_01442 or ORA_01434 
     or ORA_01543 or ORA_00904 or ORA_02261 or ORA_04043 or ORA_02289 
    then p(l_ignore_txt || SQLERRM || l_footer); 
    when OTHERS then 
    p(SQLERRM); 
    p(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); 
    p(l_footer); 
    RAISE; 
end; 
/
show err 

用例:

set serveroutput on 
begin 
re_run_ddl(' 
create table test 
(
    id number, 
    s  varchar2(30) 
) 
'); 
end; 
/
exec re_run_ddl('drop table test'); 
exec re_run_ddl('drop table test'); 
exec re_run_ddl('drop table test'); 

輸出:

EXEC: 
-------------------- 

create table test 
(
    id number, 
    s  varchar2(30) 
) 

-------------------- 
done. 

PL/SQL procedure successfully completed. 

EXEC: 
-------------------- 
drop table test 
-------------------- 
done. 

PL/SQL procedure successfully completed. 

stx11de2> EXEC: 
-------------------- 
drop table test 
-------------------- 
IGNORING --> ORA-00942: table or view does not exist 
******************** 

PL/SQL procedure successfully completed. 

stx11de2> EXEC: 
-------------------- 
drop table test 
-------------------- 
IGNORING --> ORA-00942: table or view does not exist 
******************** 

PL/SQL procedure successfully completed. 
3

你可以做兩件事情

  • 定義要忽略(這裏ORA-00942)

  • 添加一個無證(及未實現)提示/ * + IF EXISTS * /那會欣喜您管理的除外。

declare 
    table_does_not_exist exception; 
    PRAGMA EXCEPTION_INIT(table_does_not_exist, -942); 
begin 
    execute immediate 'drop table continent /*+ IF EXISTS */'; 
    exception when table_does_not_exist then 
     DBMS_OUTPUT.PUT_LINE('Ignoring table or view does not exist') 
    ; 
end; 
/

附加說明:的

exception when others then null; 

的使用可能是危險的,例如,你還忽略錯誤,如表空間脫機,當表不掉線

0
set echo on 
set serveroutput on 
alter session set current_schema=WORK_ODI; 
set verify off 
set pause off 

WHENEVER OSERROR EXIT FAILURE ROLLBACK 
drop table continent; 
WHENEVER OSERROR CONTINUE