PLS-00497:不能在 INTO 列表中的单行和多行 (BULK) 之间混合

Posted

技术标签:

【中文标题】PLS-00497:不能在 INTO 列表中的单行和多行 (BULK) 之间混合【英文标题】:PLS-00497: cannot mix between single row and multi-row (BULK) in INTO list 【发布时间】:2015-11-08 11:57:50 【问题描述】:

我创建了一个使用BULK COLLECT 在两个表中显示数据的程序,但我一直收到此错误。

PLS-00497: cannot mix between single row and multi-row (BULK) in INTO list

但是,如果我删除 BULK COLLECT 并在语句中包含 where 子句,它会起作用。

create or replace PROCEDURE sktReport IS

  TYPE inventory_table_type is RECORD (
                    v_WH_ID                  INVENTORY.WH_ID%TYPE,
                    v_wa_Product_quantity_id Product_quantity.ST_ID%TYPE); 
  v_inventory_table inventory_table_type;
BEGIN

  SELECT INVENTORY.WH_ID, Product_quantity.ST_ID,  
    BULK COLLECT INTO
     v_inventory_table.v_WH_ID, 
     v_inventory_table.v_wa_Product_quantity_id,  
   FROM INVENTORY
  INNER JOIN Product_quantity
     ON Product_quantity.ST_ID = INVENTORY.ST_ID;

  FOR i IN v_inventory_table.v_WH_ID..v_inventory_table.v_WH_ID
  LOOP
    DBMS_OUTPUT.PUT_LINE ('ID : ' || v_inventory_table.v_WH_ID
                          || ' quantity ID : ' || v_inventory_table.v_in_Product_quantity_id);
  END LOOP;

END;

【问题讨论】:

【参考方案1】:

在这里,我演示了一个简单的示例来复制您的场景。请看下面的代码。这可能会对您有所帮助。

SET serveroutput ON;
DECLARE
TYPE AV_TEST
IS
  RECORD
  (
    lv_att1 PLS_INTEGER,
    lv_att2 PLS_INTEGER );
type av_test_tab
IS
  TABLE OF av_test;
  av_test_tab_av av_test_tab;
BEGIN
  NULL;
  SELECT LEVEL,
    LEVEL+1 BULK COLLECT
  INTO av_test_tab_av
  FROM DUAL
    CONNECT BY LEVEL < 10;
  dbms_output.put_line(av_test_tab_av.count);
  FOR I IN av_test_tab_av.FIRST..av_test_tab_av.LAST
  LOOP
    dbms_output.put_line('working fine '||av_test_tab_av(i).lv_att1||' '||av_test_tab_av(i).lv_att2);
  END LOOP;
END;

【讨论】:

【参考方案2】:

这是一个简单的展示,我刚刚写的可能对你有帮助:)

SET SERVEROUTPUT ON;
DECLARE
  TYPE t_some_type IS RECORD (
    the_id  NUMBER
    ,the_name VARCHAR2(1)
  );
  TYPE t_some_type_tab IS TABLE OF t_some_type;

  lt_some_record  t_some_type;
  lt_some_array t_some_type_tab := NEW t_some_type_tab();
BEGIN

  WITH some_values AS (
    SELECT
      DECODE(LEVEL,1,1,2,2,3,3,4,4) AS the_id
      ,DECODE(LEVEL,1,'A',2,'B',3,'C',4,'D') AS the_name
    FROM
      dual
    CONNECT BY LEVEL < 5
  )
  SELECT
    sv.the_id
    ,sv.the_name
  BULK COLLECT INTO -- use this to select into an array/collection type variable
    lt_some_array
  FROM
    some_values sv;

  DBMS_OUTPUT.PUT_LINE(lt_some_array.COUNT);

  WITH some_values AS (
    SELECT
      DECODE(LEVEL,1,1,2,2,3,3,4,4) AS the_id
      ,DECODE(LEVEL,1,'A',2,'B',3,'C',4,'D') AS the_name
    FROM
      dual
    CONNECT BY LEVEL < 5
  )
  SELECT
    sv.the_id
    ,sv.the_name
  INTO -- use this to select into a regular variables
    lt_some_record.the_id
    ,lt_some_record.the_name
  FROM
    some_values sv
  WHERE
    sv.the_id = 1;

  DBMS_OUTPUT.PUT_LINE(lt_some_record.the_id||': '||lt_some_record.the_name);

  -- you can also insert such record into your array type variable
  lt_some_array := NEW t_some_type_tab();
  lt_some_array.EXTEND; -- extend the array type variable (so it could store one more element, than now - which was 0)
  lt_some_array(lt_some_array.LAST) := lt_some_record; -- assign the first element of array type variable

  DBMS_OUTPUT.PUT_LINE(lt_some_array.COUNT||'  '||lt_some_array(lt_some_array.LAST).the_id||': '||lt_some_array(lt_some_array.LAST).the_name);

END;
/

此外,由于您想遍历结果,您可以只使用游标(隐式或显式),例如

DECLARE
  -- cursor declaration
  CURSOR c_some_cursor IS
  WITH some_values AS (
    SELECT
      DECODE(LEVEL,1,1,2,2,3,3,4,4) AS the_id
      ,DECODE(LEVEL,1,'A',2,'B',3,'C',4,'D') AS the_name
    FROM
      dual
    CONNECT BY LEVEL < 5
  )
  SELECT
    sv.the_id
    ,sv.the_name
  FROM
    some_values sv;

BEGIN
  -- using explicit, earlier declared cursor
  FOR c_val IN c_some_cursor
  LOOP
    DBMS_OUTPUT.PUT_LINE(c_val.the_id||': '||c_val.the_name);
  END LOOP;


  -- using implicit, not declared cursor
  FOR c_val IN (
    WITH some_values AS (
      SELECT
        DECODE(LEVEL,1,1,2,2,3,3,4,4) AS the_id
        ,DECODE(LEVEL,1,'A',2,'B',3,'C',4,'D') AS the_name
      FROM
        dual
      CONNECT BY LEVEL < 5
    )
    SELECT
      sv.the_id
      ,sv.the_name
    FROM
      some_values sv
  )
  LOOP
    DBMS_OUTPUT.PUT_LINE(c_val.the_id||': '||c_val.the_name);
  END LOOP;
END;
/

【讨论】:

以上是关于PLS-00497:不能在 INTO 列表中的单行和多行 (BULK) 之间混合的主要内容,如果未能解决你的问题,请参考以下文章

如何激活列表中的单行?

如何在单行代码中删除 python 3 中类列表中的 [ , ] 和单引号? [关闭]

MySQL——DMLDDL语言

更新列表视图中的单行以显示隐藏的文本视图

将带有嵌套列表的列表转换为带有嵌套数据框的单行小标题

table中的单行省略,并不能让td能自适应