编辑:使用SQL-Server 2008
我有一个包含多列的AccountHistory表。与此案例相关的是Account_FK,ValidTo,ValidFrom
我尝试使用以下方法将新值插入此表:
INSERT INTO AccountHistory (Account_FK, ValidTo, ValidFrom)
SELECT Account_FK, ValidTo, ValidFrom
FROM someOtherTable
问题是: 如果AccountHistory中存在具有相同Account_FK的现有行,则插入的行应将其ValidFrom日期设置为当前日期。 ValidTo应为null。旧的AccountHistory-row应将其ValidTo日期从null更新为当前日期。 如果没有其他具有相同Account_FK的行,则validFrom日期应设置为系统默认开始日期,例如1990-01-01
这是如何最容易和优雅地解决的?我知道触发器可能是事情,但如果有更好的方法,那么我想听听你的建议。
ValidFrom字段是一个非空字段,因此我无法在其中插入任何null。
答案 0 :(得分:0)
如果使用2008,您可以使用合并声明 - Solutions for INSERT OR UPDATE on SQL Server - 请参阅Keith关于三分之一的答案。那会有用吗?
答案 1 :(得分:0)
最简单的答案是删除ValidTo
字段,该字段实际上是派生的字段(您通常不应存储)。然后,您只需要插入相关条目,并且可以相当简单地导出所需的值(需要聚合的自连接)。
但是,我有点担心如果条目存在,你将覆盖给定的ValidFrom
日期 - 你实际上是无法回溯历史记录,并且新条目将永远是'新的,现在有效的,这是极不可能的。首先,如果您插入多个条目,可能不会有一个附加的插入订单,这将立即对此进行破坏。如果有必要,这也使得无法更新条目(请注意:这不一定是出于恶意目的 - 有时候有良好的商业理由来回溯“符合条件的”历史记录。但是,包括入境时间戳,用于审计)。此外,当你在同一天有多个条目时会发生什么 - 你怎么知道哪一个是正确的(所以你确定你真的不想要时间戳)?
除此之外,这里是两个语句(在DB2上测试)我会用你来修改表格。
首先,使用insert语句来处理新条目:
INSERT INTO AccountHistory (Account_FK, ValidTo, ValidFrom)
SELECT a.Account_FK, CASE WHEN b.Account_FK IS NULL
THEN a.ValidTo
ELSE NULL END,
CASE WHEN b.Account_FK IS NULL
THEN a.ValidFrom
ELSE CURRENT_DATE END
FROM SomeOtherTable as a
LEFT JOIN (SELECT DISTINCT Account_FK
FROM AccountHistory) as b
ON b.Account_FK = a.Account_FK
用于填充'ValidTo'日期的更新语句(这会获取所有内容,而不仅仅是插入的内容):
UPDATE AccountHistory as a SET ValidTo = (SELECT MIN(b.ValidFrom)
FROM AccountHistory as b
WHERE a.Account_FK = b.Account_FK
AND b.ValidFrom > a.ValidFrom)
WHERE ValidTo IS NULL
AND EXISTS (SELECT '1'
FROM AccountHistory as b
WHERE a.Account_FK = b.Account_FK
AND b.ValidFrom > a.ValidFrom)