【发布时间】: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