无法将值存储到 oracle 中的嵌套表中

Posted

技术标签:

【中文标题】无法将值存储到 oracle 中的嵌套表中【英文标题】:Not able to store values to a nested table in oracle 【发布时间】:2012-10-16 15:53:55 【问题描述】:

我正在尝试编写一个函数来根据用户在月度报告中所做的选择来显示月度数据的值。下面的代码 sn-p 只是试图在嵌套表中获取值,一旦数据成功加载到嵌套表中,我将调用该函数来显示表。我尝试了几件事;但是在加载数据时遇到了问题。以下是创建此函数的 2 个不同的 SQL,但它们都在错误值方面出现相同的错误;我尝试了一些方法但无济于事:

片段 1:

/* Formatted on 10/16/2012 8:40:45 AM (QP5 v5.215.12089.38647) */

CREATE OR REPLACE TYPE tempObject AS OBJECT
(
   kpiid number,
   kpigroup VARCHAR2 (300)
);

CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;


CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
   mainarea IN VARCHAR2)

   RETURN tempTable
IS
   MonthlyData   temptable := temptable ();
   n             INTEGER := 0;

BEGIN

   IF (mainarea = 'ALL')

   THEN
      FOR r IN (SELECT DISTINCT kpiid, kpigroup
                  FROM kpi_summary_reporting
                 WHERE kpifrequency = 'Monthly' AND active_ind = 'Y')
      LOOP
         monthlydata.EXTEND;
         n := n + 1;
         monthlydata (n) := tempobject (r.kpiid, r.kpigroup);
      END LOOP;
  END IF;

   RETURN MonthlyData;
END;

错误:[错误] PLS-00306 (26: 29):PLS-00306:调用“TEMPOBJECT”时参数的数量或类型错误

片段2:

/* Formatted on 10/16/2012 8:27:22 AM (QP5 v5.215.12089.38647) */
CREATE OR REPLACE TYPE tempObject AS OBJECT
(
   kpiid NUMBER,
   kpigroup VARCHAR2 (300)
);

CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;


CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
   mainarea IN VARCHAR2)
   RETURN tempTable
AS
   MonthlyData   temptable := temptable ();
BEGIN
   IF (mainarea = 'ALL')
   THEN
      SELECT DISTINCT ksr.kpiid, ksr.kpigroup
        INTO MonthlyData 
        FROM kpi_summary_reporting ksr
       WHERE kpifrequency = 'Monthly' AND active_ind = 'Y';
   ELSE
      SELECT DISTINCT kpiid, kpigroup
        INTO MonthlyData
        FROM kpi_summary_reporting;
   END IF;

   RETURN MonthlyData;
END;

错误:[错误] ORA-00947 (24: 9): PL/SQL: ORA-00947: 没有足够的值

【问题讨论】:

【参考方案1】:

我会做这样的事情,假设数据足够小,可以将其完全加载到服务器 PGA 中的嵌套表中。如果数据量较大,您可能希望使用流水线表函数。

由于您的嵌套表是对象类型表,因此您需要使用对象类型构造函数。

CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
   mainarea IN VARCHAR2)
   RETURN tempTable
IS
   MonthlyData   temptable;
BEGIN
   IF (mainarea = 'ALL')
   THEN
      SELECT tempObject( kpiid, kpigroup )
        BULK COLLECT INTO monthlydata
        FROM kpi_summary_reporting
       WHERE kpifrequency = 'Monthly' 
         AND active_ind = 'Y';
   END IF;

   RETURN MonthlyData;
END;

当我在查询中看到DISTINCT 时,我总是很怀疑。您真的希望获得需要删除的重复行吗?如果没有,您最好像我上面所做的那样删除DISTINCT。如果您确实需要DISTINCT,那么您的对象类型将需要MAPORDER 方法,这会使示例复杂一些。

这个工作的演示

SQL> CREATE OR REPLACE TYPE tempObject AS OBJECT
  2  (
  3     kpiid NUMBER,
  4     kpigroup VARCHAR2 (300)
  5  );
  6  /

Type created.

SQL> CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
  2  /

Type created.

SQL> create table kpi_summary_reporting (
  2  kpiid integer,
  3  kpigroup varchar2(300),
  4  kpifrequency varchar2(30),
  5  active_ind varchar2(1)
  6  );

Table created.

SQL> insert into kpi_summary_reporting values( 1, 'Foo', 'Monthly', 'Y' );

1 row created.

SQL> ed
Wrote file afiedt.buf

  1  CREATE OR REPLACE FUNCTION Monthly_All_Data (
  2     mainarea IN VARCHAR2)
  3     RETURN tempTable
  4  IS
  5     MonthlyData   temptable;
  6  BEGIN
  7     IF (mainarea = 'ALL')
  8     THEN
  9        SELECT tempObject( kpiid, kpigroup )
 10          BULK COLLECT INTO monthlydata
 11          FROM kpi_summary_reporting
 12         WHERE kpifrequency = 'Monthly'
 13           AND active_ind = 'Y';
 14     END IF;
 15     RETURN MonthlyData;
 16* END;
 17  /

Function created.

SQL> select monthly_all_data( 'ALL' ) from dual;

MONTHLY_ALL_DATA('ALL')(KPIID, KPIGROUP)
--------------------------------------------------------------------------------
TEMPTABLE(TEMPOBJECT(1, 'Foo'))

【讨论】:

如果我尝试运行此查询,我会收到以下错误:[错误] ORA-02315 (10: 14): PL/SQL: ORA-02315: 默认构造函数的参数数量不正确跨度> @user1750578 - 您的系统中定义的tempObject 与您的问题中定义的方式完全相同吗?如果我在我的架构中创建一个虚拟的 kpi_summary_reporting 表并删除 KPI_HORIZON 架构限定符,则代码可以在我的环境中运行。

以上是关于无法将值存储到 oracle 中的嵌套表中的主要内容,如果未能解决你的问题,请参考以下文章

当嵌套表属于记录类型时,如何将数据填充到 Oracle 中的嵌套表中

如果值不存在,将值插入 MySQL 表?

要使用嵌套表插入表的Oracle存储过程?

在 Oracle 10g 中创建嵌套过程

在 hive 外部表中存储嵌套的 json,其字段由 \ 分隔

Oracle - 向嵌套表添加方法(过程)