PLSQL - 检查对象表中是否存在对象 - 类型没有映射

时间:2016-09-29 08:13:19

标签: oracle plsql

我有一个程序,它有类型表对象的变量:

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; 个对象并检查该对象是否已经存在如下:

join

但是使用此代码我收到以下错误:

  

错误:PLS-00801:内部错误[*** ASSERT at file pdw4.c,line   2181;类型0x0x7f991127aef8没有MAP方法。   NR_WIZARDVALIDATIONS__CUSTOMISATIONS__B__166833 [33]

我不确定是否可以进行这种比较,也许有人可以澄清这一点。

谢谢

1 个答案:

答案 0 :(得分:2)

不幸的是,如果你在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;

(对不起:我知道,在上面的示例中切换PlSql和SQL-Context非常耗时,但除此之外,您必须编写一个函数,通过迭代整个列表来测试ID的存在)