将有效记录从SP插入到有效表中,并将无效记录插入到无效SP中

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

我有两个存储过程,它们过滤表上的记录并给出结果。以下是存储过程。

SELECT distinct  TO_CHAR(sp.RJ_SPAN_ID) AS SPAN_ID
               , TO_CHAR(sp.RJ_MAINTENANCE_ZONE_CODE) AS MAINT_ZONE_CODE
from  APP_FTTX.span@SAT sp
INNER JOIN APP_FTTX.transmedia@SAT tm  -- transmedia added
on sp.RJ_SPAN_ID = tm.RJ_SPAN_ID
WHERE length(sp.RJ_SPAN_ID) = length(tm.RJ_SPAN_ID)
and sp.RJ_MAINTENANCE_ZONE_CODE = tm.RJ_MAINTENANCE_ZONE_CODE
and sp.INVENTORY_STATUS_CODE = tm.INVENTORY_STATUS_CODE
AND LENGTH(sp.RJ_SPAN_ID) = 21
AND (sp.RJ_SPAN_ID LIKE ('%SPN%') 
     OR sp.RJ_SPAN_ID LIKE ('%SPQ%') 
     OR sp.RJ_SPAN_ID LIKE ('%SPR%')    
     OR sp.RJ_SPAN_ID LIKE ('%SPS%'))
AND (sp.RJ_SPAN_ID LIKE ('%_BU') 
     OR sp.RJ_SPAN_ID LIKE ('%_MP'))
AND sp.INVENTORY_STATUS_CODE = 'IPL'
AND sp.RJ_MAINTENANCE_ZONE_CODE = 'INMUNVMB01'
AND (sp.RJ_INTRACITY_LINK_ID NOT LIKE ('%\_9%') ESCAPE '\' 
     OR sp.RJ_INTRACITY_LINK_ID IS NULL);

上面的SP返回4条记录,这些是我要插入表中的有效记录。

现在下面有另一个SP,它返回7条记录。

SELECT distinct  TO_CHAR(sp.RJ_SPAN_ID) AS SPAN_ID
               , TO_CHAR(sp.RJ_MAINTENANCE_ZONE_CODE) AS MAINT_ZONE_CODE
from  APP_FTTX.span@SAT sp
-- INNER JOIN APP_FTTX.transmedia@SAT tm  -- transmedia added
--  on sp.RJ_SPAN_ID = tm.RJ_SPAN_ID
-- WHERE length(sp.RJ_SPAN_ID) = length(tm.RJ_SPAN_ID)
--  and sp.RJ_MAINTENANCE_ZONE_CODE = tm.RJ_MAINTENANCE_ZONE_CODE
--   and sp.INVENTORY_STATUS_CODE = tm.INVENTORY_STATUS_CODE
WHERE LENGTH(sp.RJ_SPAN_ID) = 21
AND (sp.RJ_SPAN_ID LIKE ('%SPN%') 
     OR sp.RJ_SPAN_ID LIKE ('%SPQ%') 
     OR sp.RJ_SPAN_ID LIKE ('%SPR%')    
     OR sp.RJ_SPAN_ID LIKE ('%SPS%'))
AND (sp.RJ_SPAN_ID LIKE ('%_BU') 
     OR sp.RJ_SPAN_ID LIKE ('%_MP'))
AND sp.INVENTORY_STATUS_CODE = 'IPL'
AND sp.RJ_MAINTENANCE_ZONE_CODE = 'INMUNVMB01'
AND (sp.RJ_INTRACITY_LINK_ID NOT LIKE ('%\_9%') ESCAPE '\' 
     OR sp.RJ_INTRACITY_LINK_ID IS NULL);

SP相似。有3条记录在第二个SP中无效。所以我想要的是:我想将其他3个无效的记录插入到另一个表中。

请提出实现的建议。

UPDATE

根据Alex的评论,我在下面的代码中实现了减号部分。

SELECT distinct  TO_CHAR(sp.RJ_SPAN_ID) AS SPAN_ID, TO_CHAR(sp.RJ_MAINTENANCE_ZONE_CODE) AS MAINT_ZONE_CODE
                                    from  APP_FTTX.span@SAT sp
                                   -- INNER JOIN APP_FTTX.transmedia@SAT tm  -- transmedia added
                                  --  on sp.RJ_SPAN_ID = tm.RJ_SPAN_ID
                                   -- WHERE length(sp.RJ_SPAN_ID) = length(tm.RJ_SPAN_ID)
                                  --  and sp.RJ_MAINTENANCE_ZONE_CODE = tm.RJ_MAINTENANCE_ZONE_CODE
                                 --   and sp.INVENTORY_STATUS_CODE = tm.INVENTORY_STATUS_CODE
                                    WHERE LENGTH(sp.RJ_SPAN_ID) = 21
                                    AND (sp.RJ_SPAN_ID LIKE ('%SPN%') OR sp.RJ_SPAN_ID LIKE ('%SPQ%') OR sp.RJ_SPAN_ID LIKE ('%SPR%')    
                                    OR sp.RJ_SPAN_ID LIKE ('%SPS%'))
                                    AND (sp.RJ_SPAN_ID LIKE ('%_BU') OR sp.RJ_SPAN_ID LIKE ('%_MP'))
                                    AND sp.INVENTORY_STATUS_CODE = 'IPL'
                                    AND sp.RJ_MAINTENANCE_ZONE_CODE = 'INMUNVMB01'
                                    AND (sp.RJ_INTRACITY_LINK_ID NOT LIKE ('%\_9%') ESCAPE '\' OR sp.RJ_INTRACITY_LINK_ID IS NULL)                                        
            MINUS

       SELECT distinct  TO_CHAR(sp.RJ_SPAN_ID) AS SPAN_ID, 
          TO_CHAR(sp.RJ_MAINTENANCE_ZONE_CODE) AS MAINT_ZONE_CODE
                                    from  APP_FTTX.span@SAT sp
                                    INNER JOIN APP_FTTX.transmedia@SAT tm  -- 
                transmedia added
                                     on sp.RJ_SPAN_ID = tm.RJ_SPAN_ID
                                    WHERE length(sp.RJ_SPAN_ID) = 
               length(tm.RJ_SPAN_ID)
                                    and sp.RJ_MAINTENANCE_ZONE_CODE = 
              tm.RJ_MAINTENANCE_ZONE_CODE
                                    and sp.INVENTORY_STATUS_CODE = 
              tm.INVENTORY_STATUS_CODE
                                    AND LENGTH(sp.RJ_SPAN_ID) = 21
                                    AND (sp.RJ_SPAN_ID LIKE ('%SPN%') OR 
                sp.RJ_SPAN_ID LIKE ('%SPQ%') OR sp.RJ_SPAN_ID LIKE ('%SPR%')    
                                        OR sp.RJ_SPAN_ID LIKE ('%SPS%'))
                                    AND (sp.RJ_SPAN_ID LIKE ('%_BU') OR 
               sp.RJ_SPAN_ID LIKE ('%_MP'))
                                    AND sp.INVENTORY_STATUS_CODE = 'IPL'
                                    AND sp.RJ_MAINTENANCE_ZONE_CODE = 
              'INMUNVMB01'
                                    AND (sp.RJ_INTRACITY_LINK_ID NOT LIKE 
               ('%\_9%') ESCAPE '\' OR sp.RJ_INTRACITY_LINK_ID IS NULL);
oracle join stored-procedures inner-join insert-update
1个回答
0
投票

我认为您最好选择LEFT JOIN

SELECT DISTINCT TO_CHAR(sp.RJ_SPAN_ID) AS SPAN_ID,
                TO_CHAR(sp.RJ_MAINTENANCE_ZONE_CODE) AS MAINT_ZONE_CODE,
                SYSDATE AS MSG_DATE
FROM   APP_FTTX.span@SAT sp
LEFT JOIN APP_FTTX.transmedia@SAT tm ON sp.RJ_SPAN_ID = tm.RJ_SPAN_ID 
                                     AND sp.RJ_MAINTENANCE_ZONE_CODE = tm.RJ_MAINTENANCE_ZONE_CODE
                                     AND  sp.INVENTORY_STATUS_CODE = tm.INVENTORY_STATUS_CODE
WHERE  LENGTH(sp.RJ_SPAN_ID) = 21
AND REGEXP_LIKE(sp.rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
AND sp.INVENTORY_STATUS_CODE = 'IPL'
AND sp.RJ_MAINTENANCE_ZONE_CODE = 'INMUNVMB01'
AND NVL(INSTR(sp.RJ_INTRACITY_LINK_ID, '_'), 1) > 0
AND tm.rj_span_id IS NULL;

注意NULL上的tm.rj_span_id检查。考虑到我们的其他逻辑,应该保证要填充该列。由于它是NULL,我们知道找不到匹配项。

我也做了其他一些调整:

  1. 底部没有进行length(sp.RJ_SPAN_ID) = length(tm.RJ_SPAN_ID)的操作。您已经检查了JOIN中的值是否相等。如果它们的值相等,则长度必须相同。
  2. 考虑使用REGEXP_LIKE简化逻辑。类似于REGEXP_LIKE(sp.rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
  3. 我将您的NOT LIKEIS NULL更改为使用NVLINSTR,但这只是我的偏爱。

关于INSERT,只需将SELECT附加到INSERT INTO table_name,就可以设置好。

© www.soinside.com 2019 - 2024. All rights reserved.