将来自 SP 的有效记录插入有效 table 并将无效记录插入无效 SP
Insert valid records from SP into valid table and Invalid records into Invalid SP
我有两个存储过程,它们过滤table上的记录并给出结果。下面是存储过程。
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 returns 4 条记录,这些是我要插入到 table 中的有效记录。
现在又多了一个SP,下面有returns 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 是相似的。第二个 SP 中有 3 条记录无效。所以我想要的是:我想将其他 3 条无效记录插入另一个 table.
请建议如何实现。
更新
根据 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);
我认为你最好做一个 LEFT JOIN
。
SELECT DISTINCT sp.RJ_SPAN_ID AS SPAN_ID,
sp.RJ_MAINTENANCE_ZONE_CODE AS MAINT_ZONE_CODE,
SYSDATE AS MSG_DATE
FROM APP_FTTX.span@SAT sp
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 NOT EXISTS (SELECT 'X'
FROM APP_FTTX.transmedia@SAT tm
WHERE tm.rj_span_id = sp.rj_span_id
AND tm.rj_maintenance_zone_code = sp.rj_maintenance_zone_code
AND tm.inventory_status_code = sp.inventory_status_code);
注意 NULL
检查 tm.rj_span_id
。考虑到我们的其他逻辑,应该保证填充该列。由于是 NULL
,我们知道未找到匹配项。
我还做了一些其他调整:
- 在底部做
length(sp.RJ_SPAN_ID) = length(tm.RJ_SPAN_ID)
没有用。您已经检查过 JOIN
期间的值是否相等。如果它们的值相等,则长度必须相同。
- 考虑使用
REGEXP_LIKE
来简化您的逻辑。像 REGEXP_LIKE(sp.rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
- 删除了列列表中的
TO_CHAR
。正如评论中所讨论的,它们已经是字符串。
- 我将你的
NOT LIKE
和 IS NULL
更改为使用 NVL
和 INSTR
,但这更符合我的偏好(我一直在玩 Code Golf 它影响了我的大脑)
至于您的 INSERT
,只需将 SELECT
附加到 INSERT INTO table_name
即可。像这样:
INSERT INTO log_table_name
SELECT DISTINCT sp.RJ_SPAN_ID AS SPAN_ID,
sp.RJ_MAINTENANCE_ZONE_CODE AS MAINT_ZONE_CODE,
SYSDATE AS UPDATED_DATE,
'YOUR_USERNAME' AS USERNAME
FROM APP_FTTX.span@SAT sp
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 NOT EXISTS (SELECT 'X'
FROM APP_FTTX.transmedia@SAT tm
WHERE tm.rj_span_id = sp.rj_span_id
AND tm.rj_maintenance_zone_code = sp.rj_maintenance_zone_code
AND tm.inventory_status_code = sp.inventory_status_code);
注意:我对 UPDATED_BY
列进行了硬编码,因为我不知道正确的值。
我有两个存储过程,它们过滤table上的记录并给出结果。下面是存储过程。
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 returns 4 条记录,这些是我要插入到 table 中的有效记录。
现在又多了一个SP,下面有returns 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 是相似的。第二个 SP 中有 3 条记录无效。所以我想要的是:我想将其他 3 条无效记录插入另一个 table.
请建议如何实现。
更新
根据 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);
我认为你最好做一个 LEFT JOIN
。
SELECT DISTINCT sp.RJ_SPAN_ID AS SPAN_ID,
sp.RJ_MAINTENANCE_ZONE_CODE AS MAINT_ZONE_CODE,
SYSDATE AS MSG_DATE
FROM APP_FTTX.span@SAT sp
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 NOT EXISTS (SELECT 'X'
FROM APP_FTTX.transmedia@SAT tm
WHERE tm.rj_span_id = sp.rj_span_id
AND tm.rj_maintenance_zone_code = sp.rj_maintenance_zone_code
AND tm.inventory_status_code = sp.inventory_status_code);
注意 NULL
检查 tm.rj_span_id
。考虑到我们的其他逻辑,应该保证填充该列。由于是 NULL
,我们知道未找到匹配项。
我还做了一些其他调整:
- 在底部做
length(sp.RJ_SPAN_ID) = length(tm.RJ_SPAN_ID)
没有用。您已经检查过JOIN
期间的值是否相等。如果它们的值相等,则长度必须相同。 - 考虑使用
REGEXP_LIKE
来简化您的逻辑。像REGEXP_LIKE(sp.rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
- 删除了列列表中的
TO_CHAR
。正如评论中所讨论的,它们已经是字符串。 - 我将你的
NOT LIKE
和IS NULL
更改为使用NVL
和INSTR
,但这更符合我的偏好(我一直在玩 Code Golf 它影响了我的大脑)
至于您的 INSERT
,只需将 SELECT
附加到 INSERT INTO table_name
即可。像这样:
INSERT INTO log_table_name
SELECT DISTINCT sp.RJ_SPAN_ID AS SPAN_ID,
sp.RJ_MAINTENANCE_ZONE_CODE AS MAINT_ZONE_CODE,
SYSDATE AS UPDATED_DATE,
'YOUR_USERNAME' AS USERNAME
FROM APP_FTTX.span@SAT sp
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 NOT EXISTS (SELECT 'X'
FROM APP_FTTX.transmedia@SAT tm
WHERE tm.rj_span_id = sp.rj_span_id
AND tm.rj_maintenance_zone_code = sp.rj_maintenance_zone_code
AND tm.inventory_status_code = sp.inventory_status_code);
注意:我对 UPDATED_BY
列进行了硬编码,因为我不知道正确的值。