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 - 检查对象表中是不是存在对象 - 类型没有映射的主要内容,如果未能解决你的问题,请参考以下文章

Python:检查范围内是不是存在对象[重复]

plsql导入dmp文件时:IMP-00041:警告:创建的对象有编译警告

检查自定义类列表中是不是存在变量[重复]

Firebase 存储安全规则:检查是不是存在另一个对象/检查对象的元数据

检查数据库中是不是存在表 - PL SQL

检查对象值是不是存在于 Javascript 对象数组中,如果不存在则将新对象添加到数组