【问题标题】:Restrict Insert based on previous insertion date根据之前的插入日期限制插入
【发布时间】:2016-04-28 05:56:23
【问题描述】:

我想根据某些条件限制在我的表中的插入。

我的桌子是这样的

col1   col2    Date Create
A        1     04/05/2016
B        2     04/06/2016
A        3     04/08/2016  -- Do not allow insert
A        4     04/10/2016  -- Allow insert

所以我想根据之前插入相同记录的天数来限制插入。

如示例所示,A 只能在前一次插入 4 天后才能再次插入表中,而不是在此之前。

我如何在 SQL/Oracle 中执行此操作的任何指针。

【问题讨论】:

    标签: sql oracle insert sql-insert


    【解决方案1】:

    您只想在不存在具有相同 col1 且日期太近的记录时插入:

    insert into mytable (col1, col2, date_create)
    select 'B' as col1, 4 as col2, trunc(sysdate) as date_create from dual ins
    where not exists
    (
      select *
      from mytable other
      where other.col1 = ins.col1
      and other.date_create > ins.date_create - 4
    );
    

    因此不会插入不需要的记录。但是,不会提出任何例外。如果你愿意,我建议使用 PL/SQL 块或插入前触发器。

    【讨论】:

    • select 'B', 4, trunc(sysdate) from dual ins 不适用于给定的子选择,我建议 select * from (select 'B' as col1, 4 as col2, trunc(sysdate) as date_create from dual) ins
    • @Frank Ockenfuss:你说得对,我忘记了别名。谢谢。
    • @Thomas Kettner: imo select * from (select 'B' ... from dual) ins 也是必需的 :-)
    • @Frank Ockenfuss:这会让我感到惊讶。
    • @Thomas Kettner:检查一下并感到惊讶
    【解决方案2】:

    如果多个进程同时向您的表写入可能存在冲突的数据,那么 oracle 数据库应该可以完成这项工作。

    这可以通过定义一个约束来检查是否已经存在具有相同col1 值小于四天的条目来解决。

    据我所知,直接定义这样的约束是不可能的。相反,定义一个物化视图并在这个视图上添加一个约束。

    create materialized view mytable_mv refresh on commit as
      select f2.col1, f2.date_create, f1.date_create as date_create_conflict
        from mytable f2, mytable f1
       where f2.col1 = f1.col1
         and f2.date_create > f1.date_create
         and f2.date_create - f1.date_create < 4;
    

    当且仅当存在冲突时,此物化视图将包含一个条目。

    现在在这个视图上定义一个约束:

    alter table mytable_mv add constraint check_date_create   
    check(date_create=  
          date_create_conflict) deferrable;
    

    它在当前事务被提交时执行(因为物化视图被刷新——正如上面声明的refresh on commit)。 如果您在自治事务中插入表mytable,这可以正常工作,例如用于日志记录表。

    在其他情况下,您可以通过dbms_mview.refresh('mytable_mv') 或使用refresh on commit 以外的其他选项强制刷新物化视图。

    【讨论】:

      猜你喜欢
      • 2015-07-01
      • 2012-02-23
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多