如果您想删除一个表(如果它存在并且为空)(如问题的标题所述),您可以按如下方式执行此操作:
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 "'|| p_tab_name ||'" has been dropped');
else
dbms_output.put_line('Table "'|| p_tab_name ||'" exists and is not empty');
end if;
exception
when l_tab_not_exists
then dbms_output.put_line('Table "'|| p_tab_name ||'" 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 "tb_test" does not exist
SQL> create table tb_test(
2 col number
3 );
table TB_TEST created.
SQL> exec droptableifempty('tb_test');
Table "tb_test" has been dropped
作为旁注。在查询num_rows
列之前[dba][all][user]_tables
,为了确定一个表的行数,你需要通过执行来收集表的统计信息dbms_stats.gather_table_stats(user, '<<table_name>>');
,否则你不会得到实际的行数。