高分请教:有一个资源管理表(res_mgnt),大概有这么几个字段:
res_id, res_status, valid_date, expire_date
分别表示:
资源ID, 资源状态, 生效时间, 失效时间对资源有一种操作是"预约",这时会在表中插入一条记录:
insert into res_mgnt values(
SEQ_RES_ID.nextval, 1, SYSDATE, SYSDATE+3
);因为预约的资源要在3天后(即expire_date字段记录的时间)变为"开放"状态,所以
要求在expire_date字段的时间到达时对此记录进行一个更新:
update res_mgnt set res_status=0 where expire_date<=sysdate类似的操作还有好几种,比如"已售"状态到expire_date到达后又要变为"冻结"状态.
"冻结"状态在过了一定时间后,又要变为"开放"状态.这个表会经常被查询,如果不及时更新得到的状态就不对.如果能在查询前进行一次更新也行,但oracle没有查询触发器,要是有就很容易实现.但也不方便通过JOB来实现.首先不可能每条记录都提交一个JOB,因为记录非常多;其次,仅在一个特定时间执行的JOB(如每小时一次)不能在expire_date到达时及时进行更新.如何才能实现在expire_date那个时间点(或者对这张表进行查询之前)对记录进行更新呢?

解决方案 »

  1.   

    用程序控制,不用oracle,呵呵。
      

  2.   

    到那个时间点去更新好像不太现实的。最多可以每天夜里或者半天执行一次,需要转换状态的都在一个过程里实现,然后用job或crontab实现。
    一般状态之间的转换都是手工触发的,很少有你说的这种机制。
      

  3.   

    如果仅仅是诸如"update res_mgnt set res_status=0 where expire_date<=sysdate"之类的需求,还是比较容易实现的,可以定义一个视图来实现.
    Create or replace view Vreg as
      select    res_id, 
         when expire_date<=sysdate then 0 
              else res_satatus
         end as  res_status, valid_date, expire_date
            from reg_mgnt; 
    这样其实也相当于每次查询都计算.
      

  4.   

    谢谢大家关注:)to dobetterthatnthink:
    你这个语法我还没见过呢,Oracle 10g以上的版本?不只是那个语句,超期后状态的转换有一个固定的转换关系.
      

  5.   

    只要能让查询返回正确的结果,不管用什么实现方式,比如用一个比较复杂的视图
    Create or replace view v_res_mgnt as
      select res_id, 0 res_satatus, valid_date, expire_date from res_mgnt
      where expire_date<=sysdate and res_satatus=1
    union all
      select res_id, 1 res_satatus, valid_date, expire_date from res_mgnt
      where expire_date<=sysdate and res_satatus=2
    union all
      ...;实际语句比这个要复杂, 状态改变时还有一些字段值要调整,不知大家还有没有什么高招,谢谢.
      

  6.   

    谢谢大家, 特别是dobetterthatnthink的回复, 看来只能使用case when语句检查expire_date进行状态转换,建如下查询视图:Create or replace view v_res as
      select 
         res_id, 
         CASE when expire_date<=SYSDATE AND res_status=1 then 0 
              when expire_date<=SYSDATE AND res_status=2 then 3 
              ...
              else res_status
         end as res_status, 
         valid_date,
         expire_date
      from res_mgnt;