对动态SQL的PL / SQL代码段感到困惑

时间:2012-08-30 08:53:34

标签: sql oracle plsql

除非我取消注释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;
/

3 个答案:

答案 0 :(得分:4)

错误是因为您使用动态sql创建表,而在for循环中使用表。 在编译过程时,编译器不知道您使用动态sql

创建了表

以下是您的选择:

  1. 使用Dynamic SQL
  2. 制作for循环
  3. 更改dymamic sql以将表创建为正常的sql语句
  4. 我更喜欢第二个选项,因为动态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;
    

答案 1 :(得分:3)

这是一个解析器错误。 <{1}}在编译时不存在。

答案 2 :(得分:1)

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

解决方案就像是

execute immediate `select 1 from tmp_bank_codes where rownum = 1` into v_tmp;