【问题标题】:Dynamic INSERT Fails in procedure, but works as static SQL动态 INSERT 在过程中失败,但作为静态 SQL 工作
【发布时间】:2017-09-04 02:20:44
【问题描述】:

我正在研究将数据从大型矩阵转置到由三列组成的表中的过程。我在将行动态插入表中时遇到了一些困难。当我尝试执行下面的过程块时,我收到一条错误消息:

ORA-00936: missing expression
ORA-06512: at line 24
00936. 00000 -  "missing expression"

该过程生成一个有效的插入语句,我可以将其复制并作为静态 SQL 执行。 立即执行 stmnt 之前的所有操作都正常工作。此外,我有一个几乎相同的程序,可以完美运行。两者之间只有一个区别。在工作版本中,插入的所有值都是“VARCHAR2”类型。我不知道如何继续进行故障排除。

declare
  type rec_type is record(
    row_name varchar2(250),
    measurement number(30,27)
    );
    my_rec rec_type;

    type cols_type is table of varchar2(10);
    cols cols_type;

    stmnt varchar2(2000);
    cur sys_refcursor;
begin
  select colnames bulk collect into cols from p100_stg1_tmnt_meta;
  for i in cols.first..cols.last loop
    stmnt := 'select site_id, '|| cols(i) ||' from p100_stg1_site_matrix';
    open cur for stmnt;
    loop
      fetch cur into my_rec;
      exit when cur%notfound;
      stmnt := 'insert into p100_stg1_site_measurement (site_id, col_name, measurement) values '||
      '('''||my_rec.row_name ||''', '''||cols(i)||''', '||my_rec.measurement||')';

      --dbms_output.put_line(stmnt);
    execute immediate stmnt;
    end loop;
  end loop;
end;
/

上述过程生成的插入语句示例:

insert into p100_stg1_site_measurement (
     site_id, 
     col_name, 
     measurement
) 
values (
    '5715_C17orf85_S500_RPHS[+80]PEKAFSSNPVVR', 
    'tmnt_2', 
    .0288709682691077
)

环境: Ubuntu 16.04 上的 SQL 开发人员 Oracle 12c 社区版。

【问题讨论】:

  • my_rec.measurement 在哪里填充?如果它为空,你会得到一个包含类似 values ('X', 'Y',) 的语句

标签: oracle plsql insert dynamic-sql execute-immediate


【解决方案1】:

你应该使用绑定变量,即

stmnt := 'insert into p100_stg1_site_measurement (site_id, col_name, measurement) 
    values (:site_id, :col, :measurement)';

execute immediate stmnt using my_rec.row_name, cols(i), my_rec.measurement;

【讨论】:

  • 这就像一个魅力,感谢您的提示。根据我自己的理解,您(或其他人)是否知道这种方式,而不是其他方式?
  • 我知道这两种方法,但是在循环中构造唯一的 SQL 语句是一种缓存破坏器,并且更容易出错。
猜你喜欢
  • 1970-01-01
  • 2022-12-03
  • 2013-08-11
  • 1970-01-01
  • 2022-11-22
  • 2013-08-26
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多