简体   繁体   English

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

[英]Confused about PL/SQL snippet with dynamic SQL

This snippet runs w/o errors unless I uncomment for loop, in which case I getting 这段代码运行W / O错误,除非我取消for循环,在这种情况下,我越来越

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

My question is why error occurs with for loop uncommented? 我的问题是为什么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;
/

The error is because you use dynamic sql to create the table and the in the for loop you are using the table. 该错误是因为您使用动态sql创建表,并且在for循环中正在使用该表。 While compiling the procedure, compiler doesnt know that you have created the table with dynamic sql 在编译过程时,编译器不知道您已使用动态sql创建表。

Here are your options: 这是您的选择:

  1. make the for loop also with Dynamic SQL 使用动态SQL进行for循环
  2. change the dymamic sql to create the table to normal sql statement 更改动态sql以将表创建为普通sql语句

I would prefer the second option, as the dynamic sql will not take the cached execution plans, thus slows down the query 我更喜欢第二种选择,因为动态sql不会采用缓存的执行计划,因此会减慢查询速度

For option 1 you could do this, replace your commented code part with the following 对于选项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;

This is a parser error. 这是解析器错误。 tmp_bank_codes doesn't exist at compile-time. tmp_bank_codes在编译时不存在。

First the engine tries to compile your anonymous script. 首先,引擎尝试编译您的匿名脚本。 In this first step tmp_bank_codes table does not exists. 在第一步中, tmp_bank_codes表不存在。

A solution would be something like 解决方案将是这样的

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM