数据库表级别的约束而不是函数

时间:2012-09-24 08:30:47

标签: database oracle plsql oracle10g constraints

我在函数中使用以下select语句来检查记录的重叠,并从应用程序前端调用此函数。

SELECT count(*),product_no 
from products p where lower(p.PRODUCT_REG_NO) ='GB-UNIGAS' 
and (NVL (p.return_date, p.end_date) >= '01-Jan-2015') 
and p.product_no in (select product_no from PRODUCT_MASTER  where  EXPIRED='N' 
                    and product_no  = p.product_no)

而不是检查记录重叠的函数,我想在表中创建一个约束,这样即使在数据库级别也不会有任何插入或更新。

如何使用上面的sql语句创建约束?

任何帮助都非常值得赞赏。

由于

2 个答案:

答案 0 :(得分:3)

如果新数据不符合您的要求,您可以创建“插入前”或更新“触发器”,检查条件并引发错误。这个link会对您有所帮助。

答案 1 :(得分:1)

在存储过程中保持这种逻辑是一个不错的选择。尝试在触发器中实现该逻辑,并以某种方式最终查看

ORA-04091: table <your table> is mutating, trigger/function may not see it

例如,在触发器中实现了该功能,您可以使用insert之类的

insert into <Yourtable> (<col1>...<coln>)
   values(val1... valn)

但如果您尝试执行此mutating table

,肯定会出现insert错误

 insert into <Yourtable> (<col1>...<coln>)
    select col1, .. coln 
      from some_table

如果您不想使用存储过程,则您的其他选择可能是viewinstead of trigger

Create or replace view <ViewName> as
  select *
    from your_table;

 create or replace trigger <Trigger_name> 
   instead of insert on <View_Name>
 begin
   -- your logic
 end;

另外

另外,为了通过约束(CHECK约束)强制执行业务规则,您可以将CHECK约束和materialized view组合如下: 为您的表创建物化视图(不要忘记先创建materialized view log),以查询违反业务规则约束的数据。

 Create materialized view MV_1
  refresh complete on commit as
  --here goes your query
  -- selecting data you want to raise exception on

添加始终为false的check约束。像这样的东西

alter table MV_1 add constraint CHK check(1=2) deferrable;

完成此操作后,当您尝试在表格中插入违反业务规则限制的数据时,您将获得check constraint <..> violated