日期:2014-05-17  浏览次数:20730 次

小问题送分来了!要的快来
有一表a有4个字段f1,f2,f3,f4.其中f1表示序号,f2表示ID,f3表示标志位(0代表未删除,1代表已删除),f4代表值
现要建一约束使得表a中同一ID所对的记录中最多只能有一条记录的f3字段为0.
也就是说同一ID不能对应两条及两条以上的未删除记录.
本人小菜一个,这问题应该不难,最先答对者得分.

------解决方案--------------------
我怎么觉得像这种条件应该去程序里控制比较好啊,在数据库中控制的是表关系,逻辑上的事儿还是去程序里控制好,因为逻辑上的东西可以要多复杂就多复杂,都在数据库里控制是不可能的,所以干脆所有逻辑都不在数据库中控制吧
------解决方案--------------------
别听楼上的。。。他这样的结果是
表a中同一ID所对的记录中最多只能有一条记录的f3字段为0,也最多只能有一条记录的f3字段为1.
楼主的意思是 可以有好几条都是1,但是只能有一条是0
------解决方案--------------------
上面的做法有问题 updating 时 不能查询 表testtriger ,所以建立一个临时表 testtriger_f2 来记录 f3=0 的所有f2的值
create table testtriger(
f1 number,
f2 number,
f3 number,
f4 number
) nologging
create table testtriger_f2(
f2 number primary key
) nologging


create or replace trigger test_triger
before insert or update or delete on testtriger
for each row
declare
v1 number;
-- local variables here
begin

if (:new.f3=0) then
if INSERTING then
--是否该ID 已经有 f3=0 的记录
select count(*) into v1 from testtriger_f2 where f2=:new.f2;
if(v1=1) then
raise TOO_MANY_ROWS ;
end if;
insert into testtriger_f2 values (:new.f2);
elsif UPDATING then
select count(*) into v1 from testtriger_f2 where f2=:new.f2 ;
if(v1=1) then
raise TOO_MANY_ROWS ;
end if;

end if ;
end if;
if DELETING then
if(:old.f3=0) then
delete from testtriger_f2 where f2=:old.f2;
insert into t_heming_record values ( 'test_tiger ' , sysdate);
end if;
end if;
end test_triger;


测试:
insert into testtriger_f2 select distinct f2 from testtriger where f3=0;
insert into testtriger values (1,2,1,4);
insert into testtriger values (2,2,0,4);
insert into testtriger values (3,2,0,4);
insert into testtriger values (3,3,0,4);

insert into testtriger values (5,5,0,4);
insert into testtriger values (6,5,1,4);
insert into testtriger values (7,5,0,4);
update testtriger set f3=0 where f1=1
update testtriger set f3=0 where f1=6
update testtriger set f3=0 where f2=5

select * from testtriger
insert into testtriger values (8,6,0,4)
delete from testtriger where f2=2

delete from testtriger_f2 where f2=2

update testtriger set f2=6 where f2=2
select * from testtriger_f2
select * from t_heming_record