当前位置: 首页 > 面试题库 >

Oracle 12在SQL中的本地集合类型上是否有问题?

蒋岳
2023-03-14
问题内容

长话短说,我建议讨论您在下面看到的代码。

运行时:

  • Oracle 11编译器提高

“ PLS-00306:调用“ PIPE_TABLE”时出现错误的数量或类型的参数提示”

“ PLS-00642:SQL语句中不允许使用本地集合类型”

  • Oracle 12编译以下软件包时没有出现此类警告,但我们对运行时感到惊讶

当按原样执行匿名块时-一切都很好(我们可以在pipe_table函数中传递一些行-不会影响)

现在,让我们取消注释行hello;或对任何过程进行调用,然后再次运行更改的匿名块,我们将得到“ ORA-22163:左手和右手边的集合不是同一类型”

问题是:Oracle 12是否允许SQL中的本地集合类型?如果是,那么代码有PACKAGE buggy_report什么问题?

CREATE OR REPLACE PACKAGE buggy_report IS

  SUBTYPE t_id IS NUMBER(10);
  TYPE t_id_table IS TABLE OF t_id;

  TYPE t_info_rec IS RECORD ( first NUMBER );
  TYPE t_info_table IS TABLE OF t_info_rec;
  TYPE t_info_cur IS REF CURSOR RETURN t_info_rec;

  FUNCTION pipe_table(p t_id_table) RETURN t_info_table PIPELINED;

  FUNCTION get_cursor RETURN t_info_cur;

END buggy_report;
/

CREATE OR REPLACE PACKAGE BODY buggy_report IS

  FUNCTION pipe_table(p t_id_table) RETURN t_info_table PIPELINED IS
    l_table t_id_table;
    BEGIN
      l_table := p;
    END;

  FUNCTION get_cursor RETURN t_info_cur IS
    l_table  t_id_table;
    l_result t_info_cur;
    BEGIN

      OPEN l_result FOR SELECT * FROM TABLE (buggy_report.pipe_table(l_table));

      RETURN l_result;
    END;
END;
/

DECLARE
  l_cur buggy_report.t_info_cur;
  l_rec l_cur%ROWTYPE;
  PROCEDURE hello IS BEGIN NULL; END;
BEGIN

  l_cur := buggy_report.get_cursor();

  -- hello;

  LOOP
    FETCH l_cur INTO l_rec;
    EXIT WHEN l_cur%NOTFOUND;
  END LOOP;

  CLOSE l_cur;

  dbms_output.put_line('success');
END;
/

问题答案:

在进一步的实验中,我们发现问题甚至比想象的要深。

例如,在包中使用不同的元素时,buggy_report我们可以ORA-03113: end-of-file on communication channel 在运行脚本时获得一个(问题中)。可以通过更改t_id_tabletoVARRAY或类型来实现TABLE .. INDEX BY ..。有很多方法和变型将我们引向不同的例外,而这些例外与本文无关。

一件更有趣的事情是,buggy_report软件包规范的编译时间最多可能需要25秒,而通常情况下大约需要0.05秒。我可以肯定地说,这取决于函数声明中TYPE t_id_table参数的存在,pipe_table在40%的安装案例中都会发生“长时间编译”。因此,似乎local collection types in SQL在编译过程中潜在地出现了问题。

因此,我们看到Oracle 12.1.0.2在实现在SQL中使用本地集合类型时显然存在一个错误。

最小的例子让ORA-22163ORA-03113跟随。在那里,我们假设与buggy_report问题中的软件包相同。

-- produces 'ORA-03113: end-of-file on communication channel'
DECLARE   
  l_cur buggy_report.t_info_cur;

  FUNCTION get_it RETURN buggy_report.t_info_cur IS BEGIN RETURN buggy_report.get_cursor(); END;    
BEGIN
   l_cur := get_it();

   dbms_output.put_line('');
END;
/

-- produces 'ORA-22163: left hand and right hand side collections are not of same type'
DECLARE  
  l_cur buggy_report.t_info_cur;

  PROCEDURE hello IS BEGIN NULL; END;
BEGIN
  l_cur := buggy_report.get_cursor;

  -- comment `hello` and exception disappears
  hello;

  CLOSE l_cur;
END;
/


 类似资料:
  • 问题内容: 我有一个关于在Oracle SQL函数中使用集合的问题。 包中有类型的定义: 问题出在功能_2中。function_2使用来自function_1的输出。当我尝试在function_2中进行选择时,会出现错误消息。错误消息“ SQL语句中不允许使用本地集合类型”。 能否请你帮忙?在函数中使用集合有什么问题? 问题答案: 要达到此目的,您应该使用类似以下内容的方法: 创建或替换类型typ

  • 问题内容: 我要实现以下功能: 如何检查向量元素类型? 请注意, 向量可能为空,因此我无法检查第一个元素是“ instanceof”整数还是String … 编辑: 好吧,我脑子里有个念头,我不知道它是否会起作用 我可以按以下方式实现checkType函数: 是否可以检查T是否为整数?! 提前致谢 问题答案: *由于 类型擦除, *泛型类型参数 在运行时不可恢复(某些特殊情况除外)。这意味着在运行

  • 问题内容: 通过使用Java反射,我们可以轻松知道对象是否为数组。判断对象是否为集合(Set,List,Map,Vector …)的最简单方法是什么? 问题答案:

  • 问题内容: 考虑下面的示例表(假设SQL Server 2005): 我正在考虑一个复合主键,该主键包含两个product_id列(我肯定会想要一个唯一约束),而不是一个单独的唯一ID列。从性能的角度来看,问题是该主键是否应该集群? 我是否还应该在每个ID列上创建一个索引,以便更快地查找外键?我相信该表在读取方面比在写入方面会受到更多的打击。 问题答案: 正如其他一些人已经说过的那样,这取决于您如

  • 问题内容: 根据 jls§8.9.2枚举主体声明 枚举声明声明终结器是编译时错误。枚举类型的实例可能永远不会完成。 由于finalizer在Garbage Collector运行之前执行,如果不存在finalizer,这是否意味着类型始终保持加载在内存中,而Garbage Collector不适用于该类型? 问题答案: 如果编译像这样的枚举 您将看到生成的字节码(即)对应于合成类: 因此,枚举的实

  • 问题内容: 如果我有一个通用类: 我想实例化几个项目,例如… …并将它们添加到集合中。如何定义集合,使其可以容纳泛型类型列表?然后,我想在某个时刻迭代集合,并使用Value属性。可能? 问题答案: 让您的泛型类从非泛型基类继承,或实现一个非泛型接口。然后,您可以拥有此类型的集合,并将其转换为用于访问集合内容的任何代码。 这是一个例子。