【发布时间】:2009-10-05 22:44:52
【问题描述】:
假设我有一条记录,其中有一列名为“名称”。每条记录都可以有生效日期,所以我还有一个生效日期和一个到期日期列。
“名称”列必须是唯一的,但只能在生效日期和到期日期的重叠期间内。我正在寻找某种有效的方法来从 sql 后端强制执行此操作(我使用的是 ms sql 2008)。
【问题讨论】:
标签: sql sql-server sql-server-2008
假设我有一条记录,其中有一列名为“名称”。每条记录都可以有生效日期,所以我还有一个生效日期和一个到期日期列。
“名称”列必须是唯一的,但只能在生效日期和到期日期的重叠期间内。我正在寻找某种有效的方法来从 sql 后端强制执行此操作(我使用的是 ms sql 2008)。
【问题讨论】:
标签: sql sql-server sql-server-2008
您可以为此使用INSERT/UPDATE trigger。
该页面上的示例 C 与您需要的类似。 Inserted 是一个伪表,您可以使用它来将插入/更新的记录连接回您的表中,以查看是否有其他日期重叠的记录,
【讨论】:
这是数据模型
Table A (
name char (32) not null,
effdt date not null,
effseq int not null,
effstatus char (1) not null,
other data columns ..
)
Primary_Key A_Key (name, effdt, effseq);
这是数据:
'A', '1/1/2009', 1, 'A', 'Otherdata'
'A', '1/1/2009', 2, 'A', 'Otherdata 2'
'B', '1/1/2009', 1, 'A', 'B data'
'B', '1/1/2009', 2, 'I', 'B Data'
规则如下:
使用 Effdt 存储该行应该使用或生效的日期。这可能不是存储/创建数据的日期。
使用 Effseq 在任何日期存储多个更新。它应该始终以 1 开头。
使用 EFFStatus 停用数据。永远不要删除有效日期架构中的数据。删除也会使审计业务变得困难。
当您“更新”一行时,永远不要更新 EFFDT 列。始终使用新的 EFFDT 创建新行。如果 EFFDT 已经存在,则使用下一个 EFFSEQ。
将 updateuserid 和 updatetimestamp 也存储在行中可能是个好主意。特别是如果您想跟踪更改。
这里是查询:
获取所有数据:
Select * from A
要获取截至今天的所有“活动行”:
Select * from A A1
where effdt = (select max (EFFDT) from A where name= A1.name
and effdt <= getdate())
and effseq = (select max(effseq) from A where name=A1.name and effdt=A1.effdt)
and eff_status = 'A'
要获取过去/未来给定日期的所有行:
用上面的实际日期替换getdate()。
如果您正在编写网络应用程序,以下是表单字段规则:
插入表格:
EFFDT : Editable, Default Value = Today
EFFSEQ : Non Editable, Default Value = "#Next".
Interpret what is "Next" in the backend.
更新表格:
EFFDT : Editable, Default= current Value.
EFFSEQ : Non-Editable, Default = "#Next"
删除表格:
All data non editable, On Delete Action, set EFF_STATUS='I'
历史编辑:
This is a "super user" feature only.
EFFDT = Non Editable, Default is Current Date
EFFSEQ = Non-Editable, Default is Current Value
所有其他字段均可编辑,并对行进行真正的更新。
【讨论】: