我需要删除Oracle表,只有它存在且2)不是空的 我编写了这段代码但是如果表不存在则代码不起作用:
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;
/
我做错了什么?请帮忙。
非常感谢提前
答案 0 :(得分:4)
如果你想删除一个表,如果它存在并且为空(如问题的标题所示),你可以按如下方式执行:
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
的{{1}}列以确定表的行数之前,您需要通过执行[dba][all][user]_tables
来收集表统计信息,否则您将无法获得实际的行数。 / p>
答案 1 :(得分:0)
在PL / SQL中它是正常的&#39;赶上例外。
如果是正确的例外,请继续使用代码的下一部分。
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;
答案 2 :(得分:-1)
当然,如果表不存在,它将无法工作。您的第二个选择将获得“未找到数据”异常,并且您没有进行任何异常处理。至少你应该在第一个IF块内移动第二个选择。最好添加异常处理。
答案 3 :(得分:-2)
这是解决此问题的简便方法:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE [sssss]';
EXCEPTION WHEN OTHERS THEN NULL;
END;