这是一个简单的脚本来检查表FOO是否存在,哪个工作正常!
declare
n number;
begin
select count(*) into n from user_tables where table_name = 'FOO';
if n>0 then
dbms_output.put_line('FOO exists.');
else
dbms_output.put_line('FOO not exists.');
end if;
end;
运行输出是“FOO not exists。”,这是我的预期。现在我想在表中存在一些流程逻辑。
declare
n number;
begin
select count(*) into n from user_tables where table_name = 'FOO';
if n>0 then
dbms_output.put_line('FOO exists.');
FOR r in (select name from FOO) loop
dbms_output.put_line(r.name);
end loop;
else
dbms_output.put_line('FOO not exists.');
end if;
end;
现在它给出了错误:
FOR r in (select name from FOO) loop
*
ERROR at line 10:
ORA-06550: line 10, column 43:
PL/SQL: ORA-00942: table or view does not exist
但为什么呢? FOO不存在。并且if块不应该像我上面的第一个脚本一样执行。
或者for循环是否必须在执行之前进行评估,因此是错误?
答案 0 :(得分:0)
执行脚本时,对象引用必须有效,除非您引用引用字符串中的对象,例如在动态SQL中。
例如,您可以将脚本更改为:
declare
n number;
v_sql_count varchar2(200);
v_sql_names varchar2(200);
TYPE namesTable IS TABLE OF VARCHAR2(200);
v_names namesTable;
begin
v_sql_count := 'select count(*) from user_tables where table_name = ''FOO''';
v_sql_names := 'select name from FOO';
execute immediate v_sql_count into n;
if n>0 then
dbms_output.put_line('FOO exists.');
execute immediate v_sql_names bulk collect into v_names;
FOR r in v_names.first .. v_names.last loop
dbms_output.put_line(v_names(r));
end loop;
else
dbms_output.put_line('FOO not exists.');
end if;
exception when others then
dbms_output.put_line('SQLERR: ' || SQLERRM);
end;
两个查询(一个用于计数,一个用于获取名称列)被写为字符串然后执行。由于引用了无效名称,因此它们不会被视为无效对象引用,脚本将会运行。
答案 1 :(得分:0)
您可以使用REF CURSOR
根据动态查询打开游标:
DECLARE
n number;
TYPE cursor_type IS REF CURSOR;
c_foo_query cursor_type;
v_result varchar2(4000);
BEGIN
SELECT COUNT(*)
INTO n
FROM user_tables
WHERE table_name = 'FOO';
IF ( n>0 )
THEN
dbms_output.put_line('FOO exists.');
OPEN c_foo_query FOR 'SELECT name FROM foo';
LOOP
FETCH c_foo_query INTO v_result;
EXIT WHEN c_foo_query%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (v_result);
END LOOP;
CLOSE c_foo_query;
ELSE
dbms_output.put_line('FOO not exists.');
END IF;
END;
/