2016-02-02 1 views
2

Я использую Oracle 12c, и мне неинтересно иметь ошибку, вызывая мою таблицу CONTINENT, если она не существует.drop table Если он существует в Oracle (IF EXIST)

Я сделал это

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

Вы уверены, что он/она не хочет 'if exists'? –

+1

Если ваш босс действительно настаивает на ключевом слове 'EXIST', попробуйте следующее:' select count (*) в c из user_tables, где EXIST (выберите null из user_tables, где 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» - это может быть очень неприятно при работе с большими SQL-скриптами, содержащими много DDL и множеством ошибок.

Так я придумал следующую процедуру, которая позволяет повторно запустить 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; 

может быть опасным, как, например, вы игнорируете также ошибки, такие как табличном в автономном режиме, когда стол НЕ DROPPED.

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 
Смежные вопросы