2013-11-14 52 views
1

我試圖運行在Oracle這個SQL腳本,並得到一個錯誤ORA-00984:列這裏不允許使用動態SQL

ORA-00984:列在這裏不允許。

declare 
    tablename varchar2(200):='imagesroom'; 
    temp varchar2(50):='room_id'; 
    iid number:=1; 
    dir varchar2(200):='imgdirroom'; 
    in_fname varchar2(100):='img1.jpg'; 
    obj ORDIMAGE; 
    ctx RAW(64) := NULL; 
begin 
    execute immediate 'INSERT INTO '||tablename||'('||temp||',extension,icon) 
    VALUES(iid,'''',ORDImage(''FILE'',upper(dir),in_fname)) 
    RETURNING icon INTO obj'; 
end; 
/ 

ERROR at line 1: 
ORA-00984: column not allowed here 
ORA-06512: at line 10 

這一個偉大的工程

INSERT INTO imagesroom(room_id,extension,icon) 
VALUES(iid,'',ORDImage('FILE',upper(dir),in_fname)) 
RETURNING icon INTO obj; 

這有什麼錯呢?

如果我去做了這樣

execute immediate 'INSERT INTO :table(:type,extension,icon) 
VALUES(:id,'''',ORDImage(''FILE'',upper(:dir),:fname)) RETURNING icon INTO obj' 
using tablename,temp,iid,dir,in_fname; 

然後

ERROR at line 1: 
ORA-00903: invalid table name 
ORA-06512: at line 10 

出現...

+0

相關:在動態SQL DDL/SCL語句爲什麼不能使用綁定變量?](HTTP://計算器.com/q/25489002/1461424) – Krumia

回答

2

首先,爲什麼第二次。插入一個PL/SQL塊的作品和差不多同一個插件動態使用execute immediate聲明不會執行?僅僅是因爲名字解析。 sert,insert您聲明的this one works great正在執行iid,dirin_fname已解析爲本地聲明的變量。在動態執行insert語句的情況下,這些iid,dir已解析爲試圖向其中插入數據的表的列名,並且根本不允許將您要插入的表的列名放入value子句中的insert聲明。使用綁定變量。

其次,約returning into條款。你需要兩個。一個作爲動態生成的insert statement(動態returning into子句)和execute immediate語句(靜態returning into子句)的一部分,以便通過插入語句值返回。或者,一個動態的returning into子句和一個OUT綁定變量(在這種情況下)。

爲此,您的匿名PL/SQL塊可能是這樣的:

declare 
    tablename varchar2(200) :='imagesroom'; 
    temp  varchar2(50) :='room_id'; 
    iid  number  :=1; 
    dir  varchar2(200) :='imgdirroom'; 
    in_fname varchar2(100) :='img1.jpg'; 
    obj  ORDIMAGE; 
    ctx  RAW(64)  := NULL; -- really unnecessary, NULL by default. 
    l_instr varchar2(4000); 
begin 

    l_instr := 'INSERT INTO ' || tablename || '('||temp||',extension,icon) 
       VALUES(:1,'''',ORDImage(''FILE'',upper(:2), :3)) 
       RETURNING icon INTO :4'; 

    execute immediate l_instr 
    using iid, dir, in_fname returning into obj; 

end; 
/ 
+0

您可以使用'使用iid,dir,in_fname,out obj' - 可以工作,那麼使用第二個'returns'子句有什麼好處呢? –

+0

謝謝,我運行這個'temp2:='img_'|| temp ||'.currval'; \t立即執行'UPDATE'|| tablename ||' SET icon = obj WHERE img_id ='|| temp2;'它的序列不能在那裏使用,sequnce的名字在temp2中,它的工作原理不是動態的,哪裏出錯? – user2993505

+1

@AlexPoole。 Alex,返回子句允許您將「* record *」返回到記錄數據類型的變量中。你不能使用'using'子句和out-bind變量來做到這一點。在這種特殊情況下(DML語句沒有返回「* record *」),除了不必爲綁定變量指定模式(OUT)以防萬一必須返回多於一個值轉換爲多個輸出綁定變量。 –

1

RETURNING INTO條款應是動態的DML語句外:

execute immediate 'INSERT INTO '||tablename||'('||temp||',extension,icon) 
    VALUES(iid,'''',ORDImage(''FILE'',upper(dir),in_fname))' 
RETURNING icon INTO obj; 

有在this documentation site about EXECUTE IMMEDIATE

+0

似乎如此,但不起作用,'因爲返回沒有用於dml。此聲明將返回有關圖標的錯誤,如果刪除它,將出現以前的錯誤 – user2993505

+0

@ user2993505對不起,我的不好。 –

1

你執行的SQL字符串內的iiddirin_fnameobj引用文字底部的例子,所以他們被解釋爲列名。您應該使用綁定變量(如圖所示10g docs

... 
begin 
    execute immediate 'INSERT INTO '||tablename||'('||temp||',extension,icon) 
    VALUES(:iid,'''',ORDImage(''FILE'',upper(:dir),:in_fname)) 
    RETURNING icon INTO :obj' 
    USING iid, dir, in_fname, OUT obj; 
end; 
/ 

您可以添加類似

dbms_output.put_line(obj.in_fname); 

...驗證obj填充