0

这个片段运行没有错误,除非我取消注释for循环,在这种情况下我得到

Error report:
ORA-06550: line 12, column 41:
PL/SQL: ORA-00942: table or view does not exist

我的问题是为什么在未注释 for 循环时会发生错误?

set serveroutput on
declare
  v_sql varchar2(2000);
  v_tmp number;
begin
  dbms_output.enable(null);
  v_sql := 'CREATE TABLE tmp_bank_codes (name varchar2(256), code varchar2(256))';
  dbms_output.put_line('Will do ' || v_sql);
  execute immediate v_sql;
  v_sql := 'INSERT INTO tmp_bank_codes (name, code) VALUES (''Bank of America'', ''BOANY (NY)'')';
  dbms_output.put_line('Will do ' || v_sql);
  execute immediate v_sql;
--for bank_code in (select name, code from tmp_bank_codes) loop
--  select 1 into v_tmp from dual;
--end loop;
execute immediate 'drop table tmp_bank_codes';
rollback;

end;
/
4

3 回答 3

4

该错误是因为您使用动态 sql 创建表并且在 for 循环中您正在使用该表。在编译过程时,编译器不知道您已经使用动态 sql 创建了表

以下是您的选择:

  1. 也使用动态 SQL 进行 for 循环
  2. 将动态sql创建表更改为普通sql语句

我更喜欢第二个选项,因为动态 sql 不会采用缓存的执行计划,从而减慢查询速度

对于选项 1,您可以这样做,将您的注释代码部分替换为以下内容

v_sql :='for bank_code in (select name, code from tmp_bank_codes) loop
        select 1 into v_tmp from dual;
        end loop';
execute immediate v_sql;
于 2012-08-30T09:00:50.167 回答
3

这是一个解析器错误。tmp_bank_codes在编译时不存在。

于 2012-08-30T09:00:40.353 回答
1

首先,引擎会尝试编译您的匿名脚本。在这第一步tmp_bank_codes表中不存在。

解决方案类似于

execute immediate `select 1 from tmp_bank_codes where rownum = 1` into v_tmp;
于 2012-08-30T09:02:52.227 回答