PLSQL - 检查对象表中是不是存在对象 - 类型没有映射
Posted
技术标签:
【中文标题】PLSQL - 检查对象表中是不是存在对象 - 类型没有映射【英文标题】:PLSQL - Check if an object exists in a table of objects - type has no mapPLSQL - 检查对象表中是否存在对象 - 类型没有映射 【发布时间】:2016-09-29 08:13:18 【问题描述】:我有一个程序获得了对象表类型的变量:
lsa_final_filter_ports t_modifylink_multicolumnlist;
lsa_initial_filter_ports t_modifylink_multicolumnlist;
t_modifylink_multicolumnlist
的定义是:
CREATE OR REPLACE TYPE "T_MODIFYLINK_MULTICOLUMNLIST" IS TABLE OF o_modifylink_multicolumnlist;
TYPE o_modifylink_multicolumnlist AS OBJECT(some properties);
lsa_final_filter_ports
变量是这样填充的
SELECT b.name INTO ls_bandwidth_name FROM bandwidth b
WHERE b.bandwidthid = lna_compatible_port_bw(i);
SELECT CAST(MULTISET(SELECT *
FROM TABLE(piosa_all_ports)
WHERE ITEMNAME4 = ls_bandwidth_name)
AS t_modifylink_multicolumnlist)
INTO lsa_final_filter_ports
FROM dual;
其中piosa_all_ports
是具有相同类型t_modifylink_multicolumnlist
的I/O 参数
第二个参数在过程开始时使用过程具有的第二个 I/O 参数进行初始化
lsa_initial_filter_ports := piosa_filtered_ports;
我想要实现的是检查lsa_final_filter_ports
中的对象是否存在于lsa_initial_filter_ports
中,如果存在则跳过在lsa_initial_filter_ports
中添加该对象,这将是外部调用过程使用的输出参数。
我尝试的是遍历 lsa_final_filter_ports
对象并检查该对象是否已经存在,如下所示:
FOR i in 1..lsa_final_filter_ports.COUNT LOOP
IF lsa_final_filter_ports(i) MEMBER OF lsa_initial_filter_ports THEN
CONTINUE;
END IF;
lsa_initial_filter_ports.EXTEND();
lsa_initial_filter_ports(lsa_initial_filter_ports.COUNT) := lsa_final_filter_ports(i);
END LOOP;
但是使用此代码,我收到以下错误:
错误:PLS-00801:内部错误 [*** ASSERT at file pdw4.c, line 2181;类型 0x0x7f991127aef8 没有 MAP 方法。 NR_WIZARDVALIDATIONS__CUSTOMISATIONS__B__166833[33]
我不确定是否可以进行这种比较,也许有人可以澄清一下。
谢谢
【问题讨论】:
您使用的是哪个 Oracle 版本?从这个link来看,这个错误发生在Oracle 10g中。 我使用的是 oracle 11.2.0 【参考方案1】:不幸的是,如果您在 PlSql 中有对象,这些对象仅存在于 RAM 中(这意味着那些不会永久存储在表中的对象),将它们分配给另一个变量总是会导致原始对象的(深层)副本。 (这确实是一个问题,如果您经常将具有嵌套对象的对象分配给工作变量并返回给集合......)
因此,您将永远无法在对象指针级别比较同一对象的两个(副本)。
您唯一能做的就是比较对象的一些独特属性。
假设您的piosa_all_ports
中有一个 ID,然后您可以修改上面的循环,并以类似的方式进行比较:
v_exists integer;
FOR i in 1..lsa_final_filter_ports.COUNT LOOP
select nvl(max(1),0)
from table(lsa_initial_filter_ports) x
where x.id = lsa_final_filter_ports(i).id;
if (v_exists = 0) then
lsa_initial_filter_ports.EXTEND();
lsa_initial_filter_ports(lsa_initial_filter_ports.COUNT) := lsa_final_filter_ports(i);
end if;
END LOOP;
(rem.:我知道,在上面的示例中切换 PlSql- 和 SQL-Context 很耗时,但否则,您必须编写一个函数,通过迭代整个列表来测试 ID 的存在)
【讨论】:
太好了,这正是我要找的,我试过了,效果很好,非常感谢以上是关于PLSQL - 检查对象表中是不是存在对象 - 类型没有映射的主要内容,如果未能解决你的问题,请参考以下文章
plsql导入dmp文件时:IMP-00041:警告:创建的对象有编译警告