在合并过程中删除客户记录,但在其他表中保存标记为 Y 的主记录

问题描述 投票:0回答:1

我遇到了一种奇怪的情况,我有一个主表,其中没有标志来识别或标记要删除的记录,所以我必须依赖 rowid。表A看起来像

客户_编号 身份代码 身份号码
1234 护照 ABCDEFGH
1234 护照 ABCDEFGH
1234 阿达尔 1234 5678 9123
5678 护照 ABCDEFGH

现在,当我在 Oracle 表单上搜索详细信息时,我使用 ABCDEFGH,它会向我显示所有具有匹配记录的客户。因此输出将与上面类似,但带有附加列(这是我的第二个表 B)作为

客户_编号 身份代码 身份号码 维持 删除 n_merge_seq
1234 护照 ABCDEFGH 是的 没有 1
1234 护照 ABCDEFGH 没有 是的 1
1234 阿达尔 1234 5678 9123 是的 没有 1
5678 护照 ABCDEFGH 没有 是的 1

还有第三个表 C,仅存储客户编号和标志,如下所示。只能维护一个客户。

客户_编号 维护 删除 n_merge_seq
1234 N 1
5678 N 1

我无法从 TableB 中删除数据,因为这是审核表,同样适用于 TableC。

我使用 min(rowid) 只保留每个 customer_no||身份代码||IdentityNumber 的最小 rowid 记录,其中 B.maintain = Yes 且 C.maintain = Y

cursor cr_save_Y is
      SELECT  y.n_cust_ref_no,y.v_iden_code,y.v_iden_no,MIN(z.rowid) row_idn
        FROM  TableC x,
              TableB   y,
              TableA z
        WHERE x.customer_no     = y.customer_no
        AND   x.n_merge_seq  = y.n_merge_seq
        AND   y.identitycode       = z.identitycode
        AND   y.identitynumber         = z.identitynumber
        AND   y.customer_no     = z.customer_no
        AND   NVL(y.v_maintain,'Y')='Y'     ---iden no to keep  
        AND   x.n_merge_cust_seq   = 1
GROUP BY y.customer_no,
      y.identitycode,
      y.identitynumber   ;

然后我像下面一样循环播放

 for i in cr_save_Y
         loop
                  
            delete from TableA
            where customer_no = i.customer_no
            and identitycode = i.identitycode 
            and identityNumber = i.identityNumber 
            and rowid <> i.row_idn;
            
         end loop;  

到这里,就可以了,因为如果 row_id 不匹配,我的记录就会被保存。问题出现在下一行代码中。在下面的代码中,我将从 TableA 中删除数据,其中如果记录是维护或删除 = 'Y',则获取记录并删除确切的记录。

delete from TableA
    where customer_no||identitycode||identitynumber in (select y.customer_no||y.identitycode||y.identitynumber
from TableC x,TableB y
where x.customer_no=y.customer_no
and x.n_merge_seq=y.n_merge_seq                                                 and nvl(y.maintain,'N')='N'                                                 and x.n_merge_seq=1 
and (x.maintain = 'Y' or x.remove='Y'); 

但是由于我无法从 TableB 中删除数据,它仍然有记录,其中 1234||passport||ABCDEFGH 将根据上述查询获取,因为 tableB.maintain = N 和 TableC.maintain = Y。因此该记录将匹配到我的 tableA 记录 1234||passport||ABCDEFGH 这样,两条记录现在都被删除了,我什么都没有了。

假设,我编写如下代码

delete from TableA
    where customer_no||identitycode||identitynumber in (select y.customer_no||y.identitycode||y.identitynumber
from TableC x,TableB y
where x.customer_no=y.customer_no
and x.n_merge_seq=y.n_merge_seq                                                 and nvl(y.maintain,'N')='N'                                                 and x.n_merge_seq=1 
and (x.remove='Y');

那么,下面的情况也无法解决目的

客户_编号 身份代码 身份号码
1234 护照 ABCDEFGH
1234 阿达尔 1234 5678 9123
5678 护照 ABCDEFGH
客户_编号 身份代码 身份号码 维持 删除 n_merge_seq
1234 护照 ABCDEFGH 是的 没有 1
1234 阿达尔 1234 5678 9123 没有 是的 1
5678 护照 ABCDEFGH 没有 是的 1

这样就只会取出5678||passport||ABCDEFGH并删除它,但我的另一条记录1234||adhar||123456789123不会被删除。

有没有办法同时满足这两种场景?上面的sql查询失败,因为如果我同时选择维护和删除,那么我担心两条记录都会被删除。

我需要如下的输出

场景一:

客户_编号 身份代码 身份号码
1234 护照 ABCDEFGH
1234 阿达尔 1234 5678 9123

场景2:

客户_编号 身份代码 身份号码
1234 护照 ABCDEFGH
sql oracle plsql
1个回答
0
投票

您是否考虑过从表 A 中删除重复的行。表中没有 2 个或更多相同的行。这只会带来问题。也许这里最好的做法是将表 A 减少为不同的行 - 删除重复的行:

Delete From tbl_a
Where rowid NOT IN  ( Select   Min( ROWID )
                      From     tbl_a
                      Group By Customer_No, IdentityCode, IdentityNumber
                    );
© www.soinside.com 2019 - 2024. All rights reserved.