2013-09-23 2 views
2

Мне нужно отбросить таблицу Oracle только в том случае, если она 1) существует И 2) НЕ пусто Я написал этот код, но если таблица не существует, код не работает:Oracle, выпадающая таблица, если она существует и пуста

DECLARE 
    rec_cnt1 NUMBER :=0; 
    rec_cnt2 NUMBER :=0; 
BEGIN 
    SELECT COUNT(*) INTO rec_cnt1 FROM ALL_TABLES WHERE TABLE_NAME = 'MyTable'; 
    SELECT num_rows INTO rec_cnt2 FROM USER_TABLES WHERE TABLE_NAME = 'MyTable'; 
    IF rec_cnt1 = 1 THEN 
    BEGIN 
    IF rec_cnt2 < 1 THEN 
     EXECUTE IMMEDIATE 'DROP TABLE MyTable cascade constraints'; 
    END IF; 
    END; 
    END IF; 
END; 
/

Что я делаю неправильно? Пожалуйста помоги.

Большое спасибо заранее

+2

Что ошибка? Что происходит? Можете ли вы дать нам более подробную информацию? – Paco

+3

Добро пожаловать в SO, ваше название вопроса противоречит вашему тексту вопроса. Должна ли таблица быть пустой или НЕ пустой? В любом случае, вы не говорите, в чем проблема. «Не работает» не очень полезно, не так ли? Мы не читатели. – OldProgrammer

+0

Как правило, у вас, вероятно, будет другое использование кода, чтобы проверить, является ли именованная таблица пустой, поэтому перерыв в другой функции. –

ответ

0

Конечно это не будет работать, если таблица не существует. Ваш второй выбор получит исключение «Нет данных», и вы не выполняете обработку исключений. По крайней мере, вы должны переместить второй выбор внутри первого блока IF. Лучше всего добавить обработку исключений.

3

Если вы хотите удалить таблицу, если она существует, и пустой (как название вопросительных государств) вы могли бы сделать это следующим образом:

create or replace procedure DropTableIfEmpty(p_tab_name varchar2) 
is 
    l_tab_not_exists exception; 
    pragma exception_init(l_tab_not_exists, -942); 
    l_is_empty number; 
    l_query  varchar2(1000); 
    l_table_name varchar2(32); 
begin 
    l_table_name := dbms_assert.simple_sql_name(p_tab_name); 
    l_query := 'select count(*) 
       from ' || l_table_name ||   
      ' where rownum = 1'; 
    execute immediate l_query 
    into l_is_empty; 

    if l_is_empty = 0 
    then 
    execute immediate 'drop table ' || l_table_name; 
    dbms_output.put_line('Table has been dropped'); 
    else 
    dbms_output.put_line('Table exists and is not empty'); 
    end if; 

exception 
    when l_tab_not_exists 
    then dbms_output.put_line('Table does not exist'); 
end; 

Когда вы пытаетесь удалить таблицу или запрос таблица, которой не существует, Oracle повысит исключение ORA-00942 и выполнение блокировки pl/sql. Мы используем оператор pragma exception_init, чтобы связать исключение ORA-00942 с нашим локально определенным исключением l_tab_not_exists, чтобы обработать его соответствующим образом.

Тестовый пример:

SQL> exec droptableifempty('tb_test'); -- tb_test table does not exists 

Table does not exist 

SQL> create table tb_test(
    2  col number 
    3 ); 

table TB_TEST created. 

SQL> exec droptableifempty('tb_test'); 

Table has been dropped 

В качестве примечания. Прежде чем запрашивать столбец num_rows из [dba][all][user]_tables, чтобы определить количество строк, которые есть в таблице, вам нужно собрать статистику таблицы, выполнив dbms_stats.gather_table_stats(user, '<<table_name>>');, иначе вы не получите фактическое количество строк.

0

В PL/SQL это «нормально», чтобы поймать исключение.

Если это правильное исключение, переходите к следующей части кода.

DECLARE 
    rec_cnt1 NUMBER :=0; 
    rec_cnt2 NUMBER :=0; 
BEGIN 
    SELECT COUNT(*) INTO rec_cnt1 FROM ALL_TABLES WHERE TABLE_NAME = 'MyTable'; 
    SELECT num_rows INTO rec_cnt2 FROM USER_TABLES WHERE TABLE_NAME = 'MyTable'; 
    IF rec_cnt1 = 1 THEN 
    BEGIN 
    IF rec_cnt2 < 1 THEN 
     EXECUTE IMMEDIATE 'DROP TABLE MyTable cascade constraints'; 
    END IF; 
    END; 
    END IF; 
EXCEPTION 
    DBMS_OUTPUT.PUT_LINE('OH DEAR AN EXCEPTION WAS THROWN DUE TO' || SQLERRM); 
    DBMS_OUTPUT.PUT_LINE('THE ORACLE CODE IS ' || SQLCODE); 
    -- if it is the oracle code for no such table, or no data selected 
    -- everything is fine. 

END; 
-1

вот простой способ решить эту проблему:

BEGIN 
    EXECUTE IMMEDIATE 'DROP TABLE [sssss]'; 
    EXCEPTION WHEN OTHERS THEN NULL; 
END; 
Смежные вопросы