2012-08-30 62 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;