【发布时间】:2013-07-16 16:57:39
【问题描述】:
我想学习一种声明式方法来解决我不时遇到的与专有日期范围相关的数据限制问题。
下面是一个简化的例子。我有这些物品的物品和价格。我希望价格的生效日期范围是互斥的,没有重叠。
根据我对 Oracle 的了解,user-defined functions are not eligible for use in CONSTRAINT declarations - 我什至无法想象如果允许它会表现得多么糟糕。所以我需要一种使用触发器的程序方法。下面还包括典型的触发源。
我对学习更好的在触发器中使用的程序逻辑不感兴趣(这只是一个简单的演示示例)。我有兴趣学习针对我(可能还有其他人)面临的相对流行的数据约束问题的更具声明性的解决方案。
作为一种实践,我想尽可能消除基于触发器的解决方案。但是,如果没有触发器,我似乎无法摆脱这个要求。
create table item ( title varchar2(32) primary key );
create table price (
item varchar2(32) not null references item (title),
price number(9,2),
effective_from date not null,
effective_to date not null,
constraint price_from_to_ck check (effective_to > effective_from ));
[REDACTED]
*(A combination of row and statement level triggers inteneded to prevent logical chronological overlap)
insert into item values ('LETTUCE');
insert into item values ('WHISKY');
insert into price values ( 'LETTUCE', 1.05, date '2013-01-01', date '2013-03-31' );
insert into price values ( 'LETTUCE', 1.08, date '2013-04-01', date '2013-06-30' );
insert into price values ( 'WHISKY', 33.99, date '2013-01-01', date '2013-05-31' );
insert into price values ( 'WHISKY', 31.15, date '2013-06-01', date '2013-07-31' );
-- should fail
insert into price values ( 'WHISKY', 30.55, date '2013-05-15', date '2013-06-05' );
【问题讨论】:
-
@BrianCamire AskTom 的第一个链接是一个程序解决方案。而且,我想我看不到您的观点或 Jeff Kemp 文章的观点,即这是一个多用户并发问题。这与非空约束具有相同的并发方面。我只担心单个交易不会违反约束。
-
我不同意。过程解决方案是一种选择(尽管您仍然需要锁定),但 AskTom 链接主要讨论基于触发器的方法。并发性比非空约束更多是一个问题,因为:a) 非空约束可以声明式地强制执行,并且,b) 非空约束一次仅适用于一行。为了说明并发问题,您发布的解决方案不会阻止两个并发事务同时插入相同(因此重叠)的行。
-
不能同时插入两行。我在问题中的示例(假设是典型的 READ COMMITTED 事务)不允许第二次插入。但是,是的,它不同于非空约束。我最终想要的是对这种约束的行为,这种约束非常像非空约束一样处理。
-
您发布的解决方案将允许同时插入重叠行。在两个 SQL*Plus 会话中尝试此操作,例如命名为 A 和 B:a) 在会话 A 中,插入一行,b) 在会话 B 中,插入具有重叠值的行,c) 在会话 A 中,提交事务,并且, d) 在会话 B 中,提交事务。你现在有一个重叠。
标签: sql oracle oracle11g date-range