首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > oracle >

2个字段指定一个范围怎么控制不能有重复或交叉

2013-08-04 
2个字段指定一个范围如何控制不能有重复或交叉?本帖最后由 newjq 于 2013-07-25 05:46:49 编辑由于业务需

2个字段指定一个范围如何控制不能有重复或交叉?
本帖最后由 newjq 于 2013-07-25 05:46:49 编辑 由于业务需要,表中tab1需要以下2个字段的值:

行号                startid   endid 
1                         1       1
2                         3       4
3                         5       8

若插入:              2       2 允许
若插入:              9       12允许
若插入:              2       3 禁止
若插入:              6       7 禁止
若修改第2行为:  2       3 允许
若修改第2行为:  2       5 禁止
也就是说所有行的数值不能有重复或交叉!!!

现在需要在后台控制,我能想到的解决方案就是写了一个触发器,编译通过,插入错误的情况可以避免,但更新错误时触发器报ora-04091错误:
create or replace trigger t_tab1_idcheck before insert or update
on tab1 for each row
declare
  ll_have   number;
  old_rowid varchar2(128);
  new_startid number;
  new_endid number;
begin
  if inserting then  
    select count(*)
      into ll_have
      from tab1
     where startid <= :new.endid
       and endif >= :new.startid;--执行成功
    if (ll_have > 0) then
      raise_application_error(-20010,'error');
    end if;
  end if;

  if updating then
    new_rowid := :old.rowid;
    new_startid := :new.startid;
    new_endid := :new.endid;
    select count(*)
      into ll_have


      from tab1
     where startid <= new_endid
       and endid >= new_startid
       and rowid <> old_rowid;--执行报错
    if (ll_have > 0) then
      raise_application_error(-20010, 'error');
    end if;
  end if;
end;

请各位大侠帮我看看如何解决这个问题!或者有别的机制可以限制!谢谢!!!
[解决办法]

-- 得用带“自治事务”的触发器,代码如下:
create table tab1(r_id number, startid number, endid number);

create or replace trigger t_tab1_idcheck before insert or update
on tab1 for each row
declare
  PRAGMA AUTONOMOUS_TRANSACTION;
  ll_have number;
begin
  if inserting then  
    select count(1)
      into ll_have
      from tab1
     where startid <= :new.endid
       and endid >= :new.startid; --执行成功
    if (ll_have > 0) then
      raise_application_error(-20010,'error');
    end if;
  end if;

  if updating then
    select count(*)
      into ll_have
      from tab1
     where startid <= :new.endid
       and endid >= :new.startid
       and rowid <> :old.rowid;  --执行报错
    if (ll_have > 0) then
      raise_application_error(-20010, 'error');
    end if;
  end if;
end;
/

insert into tab1(r_id,startid,endid)


values(1,1,1);
insert into tab1(r_id,startid,endid)
values(2,3,4);
insert into tab1(r_id,startid,endid)
values(3,5,8);
commit;

insert into tab1(r_id,startid,endid)
values(4,2,2);
commit;

insert into tab1(r_id,startid,endid)
values(5,9,12);

commit;

insert into tab1(r_id,startid,endid)
values(6,2,3);
commit;

insert into tab1(r_id,startid,endid)
values(7,6,7);
commit;

热点排行