【问题标题】:'insert into' in 'execute immediate' clause在“立即执行”子句中“插入”
【发布时间】:2013-12-09 18:34:12
【问题描述】:

请您检查一下并告诉我为什么会出错?它应该怎么看?我不知道这里有什么问题。我需要在一个函数中创建一个表,并在同一个函数中将数据插入到这个表中:

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.

错在哪里?

【问题讨论】:

  • 输入了一个没有关键字 VALUES 或 SELECT 的 INSERT 语句。 VALUES 子句或 SELECT 子查询必须跟在 INSERT INTO 子句之后。
  • 我在 ||a|| 之后看到了单词 values。

标签: sql plsql insert execute-immediate


【解决方案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;

那你就知道动态命令有什么问题了。

【讨论】:

    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-20
      相关资源
      最近更新 更多