'insert into'in'immediate immediate'子句

时间:2013-12-09 18:34:12

标签: sql plsql insert execute-immediate

你能检查一下并告诉我为什么我有错误吗?应该怎么样?我不知道这里有什么问题。我需要在函数中创建一个表,并在同一个函数中将数据插入到该表中:

create or replace
function new_tab ( pyt IN varchar2) return number
IS
a number;
b varchar2(20);
begin
a:= ROUND(dbms_random.value(1, 3));
b:='example';

-- This works perfect
execute immediate 'CREATE TABLE create_tmp_table'|| a  ||'(i VARCHAR2(50))';

-- Here`s the problem
execute immediate 'insert into create_tmp_table'||a|| 'values ('|| b ||')'; 

exception
when others then
dbms_output.put_line('ERROR-'||SQLERRM);

return 0;
end;

我的结果是: ERROR-ORA-00926: missing VALUES keyword. Process exited.

错误在哪里?

2 个答案:

答案 0 :(得分:1)

在创建动态插入命令时,必须按原样创建它。所以你缺少varchar的值的单引号:

execute immediate 
     'insert into create_tmp_table'||a|| ' values ('''|| b ||''');'; 
                                                    ^here     ^and here

对此类错误的一个好建议是进行一些调试。在您的情况下,您可以创建一个varchar2变量并将插入放在其上,然后使用dbms_output.put_line到此变量。然后,您将拥有可以直接在数据库上测试的sql命令。类似的东西:

declare
   sqlCommand varchar2(1000);
   --define a and b
begin
   --put some values in a and b
   sqlCommand := 'insert into create_tmp_table'||a|| ' values ('''|| b ||''');';
   dbms_output.put_line(sqlCommand);
end;

然后你就会知道动态命令有什么问题。

答案 1 :(得分:0)

execute immediate 'insert into TABLE'||a||' (COLUMN_NAME) values (:val)' using b;

这样您就不必费心去除值(SQL注入黑客)并正确地转换类型。

http://docs.oracle.com/cd/B13789_01/appdev.101/b10807/13_elems017.htm