使用表 B 中的数据更新表 A 时出现问题

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

在 DB2 中,我有一个“实时”表,其中的数据每天都会复制到结构相同的备份表中。由于部分实时数据在备份后可能会发生变化,因此需要稍后更新相应的列。我试图用以下 SQL 来实现这一点:

UPDATE
    table_a hist
SET
    someCol = (
    SELECT
        someCol
    FROM
        table_b doc
    WHERE
        hist.someCol = doc.someCol)
WHERE
    EXISTS (
    SELECT
        *
    FROM
        table_b doc
    WHERE
        hist.ID = doc.ID
        AND (HIST.someCol != Doc.someCol
            OR (HIST.someCol IS NULL
                AND doc.someCol IS NOT NULL)));

这会导致以下错误:

The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row.

由于尽管进行了扩展搜索,但我在查询中找不到任何错误,因此我尝试了合并:

MERGE INTO table_a hist
USING (SELECT DISTINCT someCol FROM table_b) doc
ON (hist.someCol != doc.someCol)
WHEN MATCHED THEN UPDATE SET hist.someCol = doc.someCol 

这会产生另一个错误:

The statement was not processed because a row of target table "MTCS.MOMS_SPLIT_DOC_HIST" was identified more than once for update, delete or insert

那么,首先哪种方法更好?我认为合并更快,但显然我还不太明白它是如何工作的。更新也更难阅读。 合并有什么问题?当我阅读它时,它应该使用 someCol 字段比较两个表,如果两个表中的两个字段不相等,则更新 table_a 中的字段。

sql db2
1个回答
0
投票

我认为即使你的合并/更新有效,它仍然会很重,特别是当你的表变得越来越大时。因此,我认为以下步骤可能会有所帮助,而不是进行繁重的查询。

  1. a 和 b 最好都有一些索引,这样有助于加入时的阅读。
  2. 您可以使用 HASH_BYTE 函数作为另一列,此函数将帮助您查找自上次更新以来是否有任何列发生更改。因此,下次您不必检查所有列,只需比较单个值即可。语法如下:
   select *, CAST(HASHBYTES  
        ('SHA2_256'  
        , ISNULL(some_cols, '') + '|'  
        + ISNULL(some_other_cols, '') + '|'  
        ) AS bigint) AS TableHash
    from table_A

所以下次你需要做的就是比较这个哈希值。

update hist
set col = doc.col
from table_a hist
join table_b doc
    on hist.some_col = doc.some_col 
where hist.TableHash <> doc.TableHash
© www.soinside.com 2019 - 2024. All rights reserved.