我创建了这个保护功能:
create or replace
FUNCTION checkTableExists (tableName varchar2)
RETURN BOOLEAN
IS c INT;
BEGIN
SELECT COUNT(*) INTO c FROM user_tables where table_name = upper(tableName);
return c = 1;
END;
我尝试像这样使用它:
IF checkTableExists ('NO_TABLE') THEN
DELETE FROM NO_TABLE;
END IF;
即使表不存在,我也会得到:
Error report:
ORA-06550: line 6, column 17:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 6, column 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
我该如何解决?动态SQL?
更新:如果运行,我不会出错:
IF checkTableExists ('NO_TABLE') THEN
dbms_output.put_line('argh');
END IF;
不输出argh
。如果我使用确实存在的表运行上述命令,则会按预期输出argh
。
答案 0 :(得分:1)
您的语句已完全解析。因此,如果您替换
DELETE FROM NO_TABLE;
通过
null;
您的陈述应该起作用。 您的错误消息有些令人误解,因为第6行是user_tables上的select,而删除是另一条语句的第2行。这使得调试更加困难。
所以您必须使用动态sql:
execute immidiate 'delete from ' || 'NO_TABLE';
答案 1 :(得分:0)
不使用保护功能;只需尝试删除表并在不存在的情况下捕获异常:
DECLARE
table_not_exists EXCEPTION;
PRAGMA EXCEPTION_INIT( table_not_exists, -942 );
BEGIN
EXECUTE IMMEDIATE 'DELETE FROM no_table';
DBMS_OUTPUT.PUT_LINE( 'deleted' );
EXCEPTION
WHEN table_not_exists THEN
DBMS_OUTPUT.PUT_LINE( 'did not exist' );
END;
/
如果您不想在许多不同的PL / SQL块中初始化异常,请在程序包中对其进行初始化:
CREATE PACKAGE exceptions IS
table_not_exists EXCEPTION;
PRAGMA EXCEPTION_INIT( table_not_exists, -942 );
END;
/
然后代码就很简单:
BEGIN
EXECUTE IMMEDIATE 'DELETE FROM no_table';
DBMS_OUTPUT.PUT_LINE( 'deleted' );
EXCEPTION
WHEN EXCEPTIONS.table_not_exists THEN
DBMS_OUTPUT.PUT_LINE( 'did not exist' );
END;
/
如果您确实要使用保护功能(建议您不要使用),则只需使用EXECUTE IMMEDIATE
:
IF checkTableExists ('NO_TABLE') THEN
EXECUTE IMMEDIATE 'DELETE FROM NO_TABLE';
END IF;