如何从包含要更新的基表中的数据的连接表中获取数据?
Posted
技术标签:
【中文标题】如何从包含要更新的基表中的数据的连接表中获取数据?【英文标题】:How to get data from a joined table which contains data from the base table that is going to be updated? 【发布时间】:2019-07-02 18:38:58 【问题描述】:我有以下代码,它使用连接 HOTLINKS 的信息更新基表 ORDERS_REPORT_BASE。更新必须发生在
1) HOTLINKS 中的 SCAC 匹配 ORDERS_REPORT_BASE 中的任何 STD_CARR_CD 列(STD_CARR_CD 或 STD_CARR_CD_EV_CDC 或 STD_CARR_CD_CUS 或 STD_CARR_CD_EV_CUS)
--> 1a 如果 STD_CARR_CD_EV_CUS 有一个值,那么它会忽略所有其他值并使用它。如果 STD_CARR_CD_CUS 有值并且 EV_CUS 为 NULL,那么它会使用它......等等
2) 根据情况,CARR_TRACKING_NUM 或 ACTUAL_TRACKING_NUM 不为空
似乎 2) 根据结果工作,但是,1) 在通过每个 CASE 时失败,当它找到 STD_CARR_CD 时,如果不匹配,则不会进入后续场景。
这是有效的代码,但它没有考虑 SCAC 以前是否存在
UPDATE GDTS.ORDERS_REPORT_BASE BASE SET BASE.HOTLINK =
CASE WHEN BASE.CARR_TRACKING_NUM_CDC IS NULL AND BASE.ACTUAL_TRACKING_NUM IS NULL THEN NULL
WHEN BASE.CARR_TRACKING_NUM_CDC IS NOT NULL AND BASE.ACTUAL_TRACKING_NUM IS NULL THEN TRIM(HOT.URL1) || TRIM(BASE.CARR_TRACKING_NUM_CDC) || TRIM(HOT.URL2)
ELSE TRIM(HOT.URL1) || TRIM(BASE.ACTUAL_TRACKING_NUM) || TRIM(HOT.URL2) END
FROM (SELECT DISTINCT SCAC, URL1, URL2 FROM GDTS.HOTLINKS) HOT WHERE
(TRIM(HOT.SCAC) = CASE WHEN BASE.STD_CARR_CD_EV_CUS IS NOT NULL
THEN BASE.STD_CARR_CD_EV_CUS
WHEN BASE.STD_CARR_CD_CUS IS NOT NULL AND BASE.STD_CARR_CD_EV_CUS IS NULL
THEN BASE.STD_CARR_CD_CUS
WHEN BASE.STD_CARR_CD_EV_CDC IS NOT NULL AND BASE.STD_CARR_CD_CUS IS NOT NULL AND BASE.STD_CARR_CD_EV_CUS IS NULL
WHEN BASE.STD_CARR_CD IS NOT NULL AND BASE.STD_CARR_CD_EV_CDC IS NULL AND BASE.STD_CARR_CD_CUS IS NULL AND BASE.STD_CARR_CD_EV_CUS IS NULL
THEN BASE.STD_CARR_CD END)
在这种情况下,HOTLINK 字段不会更新,因为 STD_CARR_CD_CUS 不是空白,但匹配不会产生任何结果('MARUUN' 不是 HOTLINK 表中的 SCAC)
它应该最终与不为空的 STD_CARR_CD 匹配(UPS 值)
我尝试在每个 HOT.SCAC equals 处添加一个 EXISTS 子句,因此它还会检查是否在表中找到了 SCAC
...
FROM (SELECT DISTINCT SCAC, URL1, URL2 FROM GDTS.HOTLINKS) HOT WHERE
(TRIM(HOT.SCAC) = CASE WHEN BASE.STD_CARR_CD_EV_CUS IS NOT NULL AND EXISTS (SELECT DISTINCT SCAC FROM GDTS.HOTLINKS WHERE TRIM(HOT.SCAC) = BASE.STD_CARR_CD_EV_CUS)
THEN BASE.STD_CARR_CD_EV_CUS
...
但是,这个添加最终导致了重复错误。似乎从 BASE 表中检索了几行以更新整个结果。
错误:[IBM][CLI Driver][DB2/LINUXX8664] SQL0788N 语句未处理 因为目标表 \"GDTS.ORDERS_REPORT_BASE\" 的一行是 多次识别更新、删除或插入。 SQLSTATE=21506
ORDERS_REPORT_BASE 中的键是 PO_ID,但为了与 HOTLINKS 表匹配,我需要使用 STD_CARR_CD 与 SCAC 中的任何一个
我需要检查任何 STD_CARR_CD 是否存在于 HOTLINKS 表中,以便 CASE 考虑它来创建匹配逻辑。如果它不存在(如图像示例),它应该转到另一个 CASE 语句。
谢谢
【问题讨论】:
【参考方案1】:您可以使用合并来更新或插入或删除。也许您可以尝试这样做以实现您想要做的事情。
MERGE INTO target_table AS target
USING (
VALUES (1, 2, 3),
(4, 5, 6),
(7, 8, 9)
-- more rows
-- Or even you can use a complex join that gives the data set you want to alter
) AS source (C1, C2, C3)
ON target.key_to_match = source.key_to_match
WHEN MATCHED AND tab.C1 != source.C1 -- or any other condition if needed
THEN UPDATE SET target.C1 = source.C1,
target.C2 = source.C2,
target.C3 = source.C3
WHEN NOT MATCHED THEN
INSERT (C1, C2, C3)
VALUES (source.C1, source.C2, source.C3)
【讨论】:
您好,感谢您的回答。我担心的是,使用 MERGE 只允许我定义 1 个 ON 子句,而我的目标是定义 4 个可能的场景。如果目标表中的键与源表中的键不匹配,那么我应该在目标表中查找另一列,看看是否可以匹配。 可以在merge里面使用case语句。例如:MERGE into TARGET_table T USING (SELECT CASE WHEN ... THEN ... WHEN ... THEN END AS col1 FROM table1 t1 JOIN table2 t2 ON t1.keycol1=t2.keycol2) S ON T.key_to_match = S.key_to_match;
【参考方案2】:
我设法使用
检查每个 CASE 语句中是否存在 SCAC...
TRIM(HOT.SCAC) IN (SELECT SCAC FROM GDTS.HOTLINKS)
...
谢谢!
【讨论】:
以上是关于如何从包含要更新的基表中的数据的连接表中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章
ORACLE 中视图更新可以更新基表中数据,视图更新应该满足啥条件?