EXECUTE IMMEDIATE语句:ORA-00984:此处不允许使用列

时间:2018-12-04 09:23:09

标签: arrays oracle loops for-loop

我正在尝试执行以下代码。我已经创建了一个数组,并希望将此数组的每个元素插入到现有表中。我为此使用了for循环。但是我收到以下错误:“ ORA-00984:此处不允许使用列”。我在做什么错了?

DECLARE
   TYPE array_status IS VARRAY(2) OF VARCHAR2(30); 
   ARRAY array_status := array_status('Planned', 'Finished');
BEGIN
   FOR i IN 1..ARRAY.COUNT LOOP
   EXECUTE IMMEDIATE 'INSERT INTO STATUS_DIM(STATUSNAAM) VALUES(' || ARRAY(i) || ')'; 
      dbms_output.put_line(array(i));
   END LOOP;
END;

1 个答案:

答案 0 :(得分:4)

您正在将值串联到SQL字符串中,结果是这样的:INSERT INTO STATUS_DIM(STATUSNAAM) VALUES(Planned);,但是值应该放在单引号之间:INSERT INTO STATUS_DIM(STATUSNAAM) VALUES('Planned');

正确的解决方案是使用绑定变量:

DECLARE
   TYPE array_status IS VARRAY(2) OF VARCHAR2(30); 
   ARRAY array_status := array_status('Planned', 'Finished');
BEGIN
   FOR i IN 1..ARRAY.COUNT LOOP
   EXECUTE IMMEDIATE 'INSERT INTO STATUS_DIM(STATUSNAAM) VALUES(:status)' using array(i); 
      dbms_output.put_line(array(i));
   END LOOP;
END;
/

然后,您无需考虑报价。

实际上,您根本不需要动态SQL:

DECLARE
   TYPE array_status IS VARRAY(2) OF VARCHAR2(30); 
   ARRAY array_status := array_status('Planned', 'Finished');
BEGIN
   FOR i IN 1..ARRAY.COUNT LOOP
     INSERT INTO STATUS_DIM(STATUSNAAM) VALUES(array(i)); 
     dbms_output.put_line(array(i));
   END LOOP;
END;
/

但是,最有效的解决方案是使用FORALL而不是循环。

DECLARE
   TYPE array_status IS VARRAY(2) OF VARCHAR2(30); 
   ARRAY array_status := array_status('Planned', 'Finished');
BEGIN
   FORALL i IN 1..ARRAY.COUNT 
     INSERT INTO STATUS_DIM(STATUSNAAM) VALUES(array(i)); 
END;
/

这将比“普通循环”更快,但缺点是您不能对每个元素使用dbms_output