多连接 'gotohell' 更新
Multi-join 'gotohell' update
我有这个 select 查询 returns 简单 table - 见下文。
我花了一整天的时间试图写一个更新语句,当 EQLOC 为 NULL 或与 HOOKNO 不同时,它应该用 HOOKNO 更新...但我失败了。
请帮忙。
SELECT ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') as hookno, eq.location_description as eqloc
FROM KEY_HOOK_CURRENT khc
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL OR
ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') <> eq.LOCATION_DESCRIPTION)
查询 returns 如下:
HOOKNO EQLOC
G00754 (null)
L02860 (null)
L04052 L12345
L01126 (null)
L01348 (null)
L01950 L56789
L00857 (null)
L04651 (null)
L03762 (null)
所以试过了
UPDATE (SELECT ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') AS hookey, eq.LOCATION_DESCRIPTION AS eqloc
FROM KEY_HOOK_CURRENT khc
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL OR (ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0')) <> eq.LOCATION_DESCRIPTION))
SET hookno = eqloc
but getting 01733 - "virtual column not allowed"
...以及许多其他查询,包括合并,但没有太多经验,所以运气不好! :(
请注意:此查询将 运行 每 10 分钟 24/7,因此它应该非常快(如果可能)并且仅在必要时更新。
我们将不胜感激。
谢谢!
鉴于设备table的主键是equipmentoid,我们可以创建MERGE语句如下:
merge into equipment tgt
using (select eq.equipmentoid,
ho.hook_office_letter || lpad(khc.hook_no, 5, '0') as hookno,
eq.location_description as eqloc
from key_hook_current khc
inner join key_holding kho on khc.key_holdingoid = kho.key_holdingoid
inner join contract con on kho.customeroid = con.customeroid
inner join vw_current_contract_period ccp on con.contract_id = ccp.contract_id
inner join contract_period cp on (ccp.contract_id = cp.contract_id and ccp.contract_period = cp.contract_period)
inner join contract_equip_period cep on cp.contract_periodoid = cep.contract_periodoid
inner join equipment eq on cep.equipmentoid = eq.equipmentoid
inner join hook_office ho on khc.hook_officeoid = ho.hook_officeoid
where
eq.product_id = 'XXX' and
(eq.location_description is null or
ho.hook_office_letter || lpad(khc.hook_no, 5, '0') <> eq.location_description)) src
on (tgt.equipmentoid = src.equipmentoid)
when matched then
update set tgt.location_description = src.hookno;
我所做的就是采用你的 select 语句,添加到对你设备 table 的主键列的引用中,这允许我们将源子查询连接回 table 并更新相关行。
看起来你想将 location_description 分成一个字母和 5 位数字代码并将其分配给 HOOK_OFFICE_LETTER 和 HOOK_NO。
UPDATE ho
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
SET HOOK_OFFICE_LETTER = SUBSTRING(eq.location_description,1,1),
--cut letter and assignto HOOK_OFFICE_LETTER
khc.HOOK_NO = SUBSTRING(eq.location_description,2,5)
--cut 5-digit code and assign to khc.HOOK_NO
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL) OR
((ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') <> eq.LOCATION_DESCRIPTION))
但您可能希望将 eq.location_description 更新为 (ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') 的值
因此,使用下一个查询:
UPDATE ho
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
SET eq.location_description = (ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0')
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL) OR
((ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') <> eq.LOCATION_DESCRIPTION))
我有这个 select 查询 returns 简单 table - 见下文。
我花了一整天的时间试图写一个更新语句,当 EQLOC 为 NULL 或与 HOOKNO 不同时,它应该用 HOOKNO 更新...但我失败了。
请帮忙。
SELECT ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') as hookno, eq.location_description as eqloc
FROM KEY_HOOK_CURRENT khc
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL OR
ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') <> eq.LOCATION_DESCRIPTION)
查询 returns 如下:
HOOKNO EQLOC
G00754 (null)
L02860 (null)
L04052 L12345
L01126 (null)
L01348 (null)
L01950 L56789
L00857 (null)
L04651 (null)
L03762 (null)
所以试过了
UPDATE (SELECT ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') AS hookey, eq.LOCATION_DESCRIPTION AS eqloc
FROM KEY_HOOK_CURRENT khc
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL OR (ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0')) <> eq.LOCATION_DESCRIPTION))
SET hookno = eqloc
but getting 01733 - "virtual column not allowed"
...以及许多其他查询,包括合并,但没有太多经验,所以运气不好! :(
请注意:此查询将 运行 每 10 分钟 24/7,因此它应该非常快(如果可能)并且仅在必要时更新。
我们将不胜感激。
谢谢!
鉴于设备table的主键是equipmentoid,我们可以创建MERGE语句如下:
merge into equipment tgt
using (select eq.equipmentoid,
ho.hook_office_letter || lpad(khc.hook_no, 5, '0') as hookno,
eq.location_description as eqloc
from key_hook_current khc
inner join key_holding kho on khc.key_holdingoid = kho.key_holdingoid
inner join contract con on kho.customeroid = con.customeroid
inner join vw_current_contract_period ccp on con.contract_id = ccp.contract_id
inner join contract_period cp on (ccp.contract_id = cp.contract_id and ccp.contract_period = cp.contract_period)
inner join contract_equip_period cep on cp.contract_periodoid = cep.contract_periodoid
inner join equipment eq on cep.equipmentoid = eq.equipmentoid
inner join hook_office ho on khc.hook_officeoid = ho.hook_officeoid
where
eq.product_id = 'XXX' and
(eq.location_description is null or
ho.hook_office_letter || lpad(khc.hook_no, 5, '0') <> eq.location_description)) src
on (tgt.equipmentoid = src.equipmentoid)
when matched then
update set tgt.location_description = src.hookno;
我所做的就是采用你的 select 语句,添加到对你设备 table 的主键列的引用中,这允许我们将源子查询连接回 table 并更新相关行。
看起来你想将 location_description 分成一个字母和 5 位数字代码并将其分配给 HOOK_OFFICE_LETTER 和 HOOK_NO。
UPDATE ho
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
SET HOOK_OFFICE_LETTER = SUBSTRING(eq.location_description,1,1),
--cut letter and assignto HOOK_OFFICE_LETTER
khc.HOOK_NO = SUBSTRING(eq.location_description,2,5)
--cut 5-digit code and assign to khc.HOOK_NO
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL) OR
((ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') <> eq.LOCATION_DESCRIPTION))
但您可能希望将 eq.location_description 更新为 (ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') 的值 因此,使用下一个查询:
UPDATE ho
INNER JOIN KEY_HOLDING kho ON khc.KEY_HOLDINGOID = kho.KEY_HOLDINGOID
INNER JOIN CONTRACT con ON kho.CUSTOMEROID = con.CUSTOMEROID
INNER JOIN VW_CURRENT_CONTRACT_PERIOD ccp ON con.CONTRACT_ID = ccp.CONTRACT_ID
INNER JOIN CONTRACT_PERIOD cp ON (ccp.CONTRACT_ID = cp.CONTRACT_ID AND ccp.CONTRACT_PERIOD = cp.CONTRACT_PERIOD)
INNER JOIN CONTRACT_EQUIP_PERIOD cep ON cp.CONTRACT_PERIODOID = cep.CONTRACT_PERIODOID
INNER JOIN EQUIPMENT eq ON cep.EQUIPMENTOID = eq.EQUIPMENTOID
INNER JOIN HOOK_OFFICE ho ON khc.HOOK_OFFICEOID = ho.HOOK_OFFICEOID
SET eq.location_description = (ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0')
WHERE
eq.PRODUCT_ID = 'XXX' AND
(eq.LOCATION_DESCRIPTION IS NULL) OR
((ho.HOOK_OFFICE_LETTER || LPAD(khc.HOOK_NO, 5, '0') <> eq.LOCATION_DESCRIPTION))