2012-08-30 64 views
0

这个片段PL/SQL代码段运行W/O错误,除非我取消for循环,在这种情况下,我越来越困惑与动态SQL

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; 
/
+0

你有什么问题吗? –

+0

我的问题是为什么'for'循环取消注释时发生错误。 –

+0

在Oracle中即时创建表并不是一个好主意。你最好一劳永逸地创建'tmp_bank_codes'作为全局临时表,那么你不需要重新创建或删除它(此外,它也会使此代码对于并发使用安全)。 –

回答

4

错误是因为您使用动态sql来创建表,并在for循环中使用表。 在编译过程中,编译器完全不认识你已经创建的表使用动态SQL

这里是你的选择:

  1. 使for循环也与动态SQL
  2. 变化dymamic SQL创建表正常的SQL语句

我宁愿第二个选项,因为动态SQL不会采取缓存的执行计划,从而会减慢查询

对于第一种情况,你能做到这一点,有以下

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; 
+0

您能否提供一个提示如何重写以解决此问题? –

+0

你要达到什么样的高层目标?这不是在运行时创建表的通用oracle方法 –

+0

顺便说一下,Oracle非常恼人地报告有问题的行的序号,并且偶尔会出现一次性错误。 –

3

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

1

首先更换您的注释代码部分发动机试图编译匿名的脚本。在这第一步tmp_bank_codes表不存在。

一种解决方案是这样的

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