将数据从 ref 游标提取到嵌套表中时出现不一致的数据类型错误

Posted

技术标签:

【中文标题】将数据从 ref 游标提取到嵌套表中时出现不一致的数据类型错误【英文标题】:Getting inconsistent datatypes error while fetching data from ref cursor into a nested table 【发布时间】:2014-05-30 10:22:21 【问题描述】:

在将数据从 ref 游标提取到嵌套表中时出现错误。这就是我正在做的事情。

对象和表类型:

CREATE OR REPLACE TYPE obj_report_org IS OBJECT
(dummy1 VARCHAR2(50),
dummy2 VARCHAR2(50),
dummy3 VARCHAR2(50),
dummy4 NUMBER(10));

CREATE OR REPLACE TYPE tab_report_org IS TABLE OF obj_report_org;

程序:

CREATE OR REPLACE PROCEDURE areaReport_test(v_name1 VARCHAR2,
    v_name2 VARCHAR2,  tab_report_set OUT tab_report_org)
IS
    str VARCHAR2(2000);
    v_num NUMBER := 1;
    recordset SYS_REFCURSOR;
    lv_tab_report_set tab_report_org := tab_report_org();
BEGIN

    str := ' SELECT tab2.dummy1 ,tab3.dummy2,tab2.dummy3,tab1.dummy4 '||
           ' FROM tab1,tab2, tab3, tab4'||
           ' WHERE <JOIN CONDITIONS>';

    OPEN recordset FOR 
        str||' START WITH tab1.name = :name1'||
            ' CONNECT BY PRIOR tab1.id = tab1.parent_id'||
            ' UNION '||
            str||' START WITH tab1.name = :name2'||
            ' CONNECT BY PRIOR tab1.id = tab1.parent_id'
        USING v_name1,v_name2;

    FETCH recordset BULK COLLECT into lv_tab_report_set;

    CLOSE recordset;

    tab_report_set := lv_tab_report_set;
END;

然后我有一个匿名块来调用该过程:

DECLARE
    l_tab_report_set tab_report_org;
BEGIN
    areaReport_test('PRASHANT',null,l_tab_report_set);
    FOR i in 1 .. l_tab_report_set.count
    LOOP
        DBMS_OUTPUT.PUT_LINE(
          l_tab_report_set(i).dummy1|| ' | ' ||
          l_tab_report_set(i).dummy2|| ' | ' ||
          l_tab_report_set(i).dummy3|| ' | ' ||
          l_tab_report_set(i).dummy4|| );
   END LOOP;
END;

运行匿名块后,我收到此错误:

ORA-00932: inconsistent datatypes: expected - got -
ORA-06512: at "AREAREPORT_TEST", line 36
ORA-06512: at line 5
00932. 00000 - "inconsistent datatypes: expected %s got %s"

似乎我们无法将数据批量提取到由 SQL 对象形成的嵌套表中。而对象中的字段序列和数据类型与选择查询匹配。

请指教。

【问题讨论】:

【参考方案1】:

我会从底部开始:

FETCH recordset BULK COLLECT into lv_tab_report_set;

您正在将一个记录集提取到对象表中。因此,记录集应该包含对象列表。

SELECT tab2.dummy1 ,tab3.dummy2,tab2.dummy3,tab1.dummy4...

它是一个列列表,而不是一个对象。这是一个对象列表:

select obj_report_org(tab2.dummy1 ,tab3.dummy2,tab2.dummy3,tab1.dummy4) ...

关于一般代码的一些评论

当您使用 UNION 而不是 UNION ALL 时,Oracle 将对结果进行排序并消除重复项(没有其他方法可以做到这一点)。所以想想你是否真的需要 UNION 并记住这是有代价的。

你 UNION 两个看起来可以组合在一起的数据集

START WITH tab1.name in (:name1, :name2)

在 ORA-22950 之后继续

您正在对元素进行隐式排序,但是 ORACLE 是如何知道如何对它们进行排序的? 通过 dummy1 或 dummy2 或 ...?

你必须选择:

    不要使用排序

    这基本上意味着没有 DISTINCT、GROUP BY、ORDER BY 和没有 UNION(你可以使用 UNION ALL)

    define 为您的对象排序


跟进ORACLE Types中的方法

您的 oracle 类型可能有其他方法,其中一些是特殊的,请注意下面的“ORDER MEMBER FUNCTION”(复制自link):

<!-- language: pl/sql -->
CREATE OR REPLACE TYPE location_typ AS OBJECT (
building_no  NUMBER,
city         VARCHAR2(40),
ORDER MEMBER FUNCTION match (l location_typ) RETURN INTEGER 
);
/
CREATE OR REPLACE TYPE BODY location_typ AS 
ORDER MEMBER FUNCTION match (l location_typ) RETURN INTEGER IS 
BEGIN 
IF building_no < l.building_no THEN
  RETURN -1;               -- any negative number will do
ELSIF building_no > l.building_no THEN 
  RETURN 1;                -- any positive number will do
ELSE 
  RETURN 0;
END IF;
END;
END;/

【讨论】:

我现在收到以下错误。请帮助在这种情况下如何创建地图方法。 ORA-22950: 不能在没有 MAP 或 ORDER 方法的情况下对对象进行排序 22950。 00000 - “不能在没有 MAP 或 ORDER 方法的情况下对对象进行排序” *原因:对象类型必须为除相等和不等比较之外的所有比较定义 MAP 或 ORDER 方法。 *Action:为对象类型定义一个 MAP 或 ORDER 方法 在这种情况下我必须使用 UNION。在这种情况下,如何为我的对象定义排序。可以举个例子吗? @prashant1988 添加了暗示排序的关键字示例和更新列表【参考方案2】:

获取它的数据类型不匹配不是问题。打开游标并获取您所写的内容是正确的。

【讨论】:

数据类型不同。期望对象时作为输入的列列表

以上是关于将数据从 ref 游标提取到嵌套表中时出现不一致的数据类型错误的主要内容,如果未能解决你的问题,请参考以下文章

求oracle高手,存储过程中取游标值时,出现数据类型不一致问题,急急

如何将嵌套哈希提取到数据库表中?

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

动态嵌套游标解决方案

mysql从一个表提取数据更新另外一个表(修复表数据的不一致)

如何从存储过程返回的游标将数据插入临时表