【问题标题】:In DB2, perform an update based on insert for large number of rows在 DB2 中,对大量行执行基于插入的更新
【发布时间】:2014-05-02 08:41:39
【问题描述】:

在 DB2 中,我需要进行插入,然后使用该插入的结果/数据更新相关表。我需要在一百万多条记录上执行此操作,并且不希望锁定整个数据库。那么,1)我如何“耦合”插入和更新语句? 2)如何确保交易的完整性(不锁定整个she-bang)?

一些伪代码应该有助于澄清

第 1 步

 insert into table1 (neededId, id)        select DYNAMICVALUE, id from tableX      where needed value is null

第 2 步

 update table2 set neededId = (GET THE DYNAMIC VALUE JUST INSERTED)     where id = (THE ID JUST INSERTED)

注意:在 table1 中,ID col 不是唯一的,所以我不能只过滤它以找到新的 DYNAMICVALUE

这应该更清楚(FTR,这可行,但我不喜欢它,因为我必须锁定表以保持完整性。如果我可以一起运行这些语句并允许更新,那就太好了引用 newAddressNumber 值。)

/****RUNNING TOP INSERT FIRST****/*

--insert a new address for each order that does not have a address id
insert into addresses
    (customerId, addressNumber, address)    
select 
    cust.Id, 
    --get next available addressNumber
    ifNull((select max(addy2.addressNumber) from addresses addy2 where  addy2.customerId = cust.id),0) + 1 as newAddressNumber,
    cust.address
from customers cust
where exists (
    --find all customers with at least 1 order where addressNumber is null
    select 1 from orders ord
    where 1=1
    and ord.customerId = cust.id
    and ord.addressNumber is null   
    )


/*****RUNNING THIS UPDATE SECOND*****/          
update orders ord1
set addressNumber = (
            select max(addressNumber) from addresses addy3 
            where addy3.customerId = ord1.customerId
            ) 
where 1=1 
    and ord1.addressNumber is null  

【问题讨论】:

  • 您是否真的需要插入到 table1 中的行超出“步骤 2”的范围,或者您是否将它们放在那里认为这是完成更新所需要做的?在什么意义上你的意思是“动态”?如果您能给我们提供实际场景或与之紧密建模的类比,这可能会有所帮助。
  • 好的。处理遗留电子商务系统,其中有一个与订单表相关的地址表。订单表对地址表有一个 FK,但它可以为空。为空时,不使用地址表。
  • ... 我们正在更新系统,现在每个订单记录器都需要一个 addressId。所以我需要为orders.addressId(fk字段)为空的每个订单插入一个新的地址记录,然后用新的addressId填充该字段。但是,更复杂的是......地址表中的 ID 字段不是唯一的;对于每个不同的客户,它是一个从 1 开始的“addressNumber”(键是 customerId 和“addressNumber”的组合)。抱歉,如果这仍然令人困惑。
  • 在上面添加了一些实际的 sql...
  • 维护类似addressNumber 的东西 - 每个客户的计数器 - 是派生信息,应尽可能避免。尤其是当您当前的策略可能需要锁定表以允许安全地获取新值时;如果您在customerId,addressNumber 上有索引,则优化器可能只能锁定受影响的行。你基本上得到了最新的行 - 你有类似insertedAt 时间戳的东西吗?每行唯一的键(通常是自动编号列)怎么样?

标签: db2 output insert-update


【解决方案1】:

IDENTITY_VAL_LOCAL 函数是一个非确定性函数,它返回最近为标识列分配的值,其中分配是由于使用 VALUES 子句的单个 INSERT 语句而发生的

【讨论】:

  • 嗯,他没有使用VALUES 子句,所以这不会有帮助。另外,没有身份列。并且addressNumber 对每个customerId 重复,所以它不能是自动生成的值...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2014-08-01
  • 1970-01-01
相关资源
最近更新 更多