我有一个关于ORACLE的问题,我编写了一个PLSQL代码来检查一个表是否存在,如果它存在,那么我从这个表中选择一些东西..pseudocode就像:
如果(表存在)从表中选择....
问题是,如果表不存在,我总是会收到错误,即使从不满足if条件并且从不执行select语句.
我认为这是因为我的代码在编译时被检查:"select from .."然后如果表不存在则会输出错误.我怎样才能解决这个问题?这里是我的代码的样子(我使用了通用名称):
DECLARE
v_table_exists NUMBER;
BEGIN
SELECT NVL(MAX(1), 0)
INTO v_table_exists
FROM ALL_TABLES
WHERE TABLE_NAME = 'TABLE_TEST';
IF v_table_exists = 1 THEN
INSERT INTO MY_TABLE(COLUMN1, COLUMN2, COLUMN3, COLUMN4)
SELECT 1234,
5678,
T.COLUMN_TEST1,
T.COLUMN_TEST2
FROM TABLE_TEST T
WHERE T.FLAG = 1;
END IF;
END;
Run Code Online (Sandbox Code Playgroud)
问题恰恰在于,您的过程无法编译,因为它引用了一个不存在的对象; 你可能需要一些动态SQL; 例如:
create or replace procedure checkTable is
vCheckExists number;
vNum number;
begin
-- check if the table exists
select count(1)
into vCheckExists
from user_tables
where table_name = 'NON_EXISTING_TABLE';
--
if vCheckExists = 1 then
-- query the table with dynamic SQL
execute immediate 'select count(1) from NON_EXISTING_TABLE'
into vNum;
else
vNum := -1;
end if;
dbms_output.put_line(vNum);
end;
Run Code Online (Sandbox Code Playgroud)
即使表不存在,该过程也会编译; 如果你现在打电话,你得到:
SQL> select count(1) from NON_EXISTING_TABLE;
select count(1) from NON_EXISTING_TABLE
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> exec checkTable;
-1
PL/SQL procedure successfully completed.
Run Code Online (Sandbox Code Playgroud)
然后,如果您创建表并再次调用该过程:
SQL> create table NON_EXISTING_TABLE(a) as select 1 from dual;
Table created.
SQL> exec checkTable;
1
PL/SQL procedure successfully completed.
Run Code Online (Sandbox Code Playgroud)
就像我展示的一样SELECT,你可以做一个UPDATE或者你需要的任何SQL查询; 如果您执行与a不同的操作SELECT,则INTO必须删除该子句.
例如,假设您需要插入到不同的表中,上面的代码应该以这种方式编辑:
if vCheckExists = 1 then
execute immediate 'insert into target(a, b, c) select a, 1, 100 from NON_EXISTING_TABLE';
end if;
Run Code Online (Sandbox Code Playgroud)