ORA-00984:这里不允许列动态sql

时间:2013-11-14 18:58:20

标签: oracle plsql oracle11g dynamic-sql

我正在尝试在oracle中运行此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

...出现

3 个答案:

答案 0 :(得分:2)

首先,为什么PL / SQL块中的第二个插入工作正常,几乎使用execute immediate语句动态执行的相同插入操作不起作用?仅仅因为名称解析。第二次插入时,您insert正在执行的this one works great语句正在执行iiddirin_fname已解析为本地声明的变量。如果动态执行insert语句,那些iiddir已解析为您尝试将数据插入的表的列名,并且根本不允许将您要插入的表的列名放在value语句的insert子句中。使用绑定变量。

其次,关于returning into条款。你需要其中两个。一个作为动态形成的insert statement(动态returning into子句)和一个execute immediate语句(静态returning into子句)的一部分,以便通过insert语句值返回出。或者,一个动态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;
/   

答案 1 :(得分: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

的底部有一个例子

答案 2 :(得分: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