长话短说,我建议讨论您在下面看到的代码。
运行时:
“ PLS-00306:调用“ PIPE_TABLE”时出现错误的数量或类型的参数提示”
“ PLS-00642:SQL语句中不允许使用本地集合类型”
当按原样执行匿名块时-一切都很好(我们可以在
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_table
toVARRAY
或类型来实现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-22163
和ORA-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属性。可能? 问题答案: 让您的泛型类从非泛型基类继承,或实现一个非泛型接口。然后,您可以拥有此类型的集合,并将其转换为用于访问集合内容的任何代码。 这是一个例子。