我正在从事有关全国选举制度的数据库项目。在为某个候选人投票时,我想自动在结果表中更新total_votes +1。所有候选人的total_votes始于零。我写了一个触发器,但是不起作用
/* I tried this trigger*/
create or replace Trigger tvc
after insert
on cast_vote
Declare
for each row
begin
update results r
set total_vote = total_vote+1
where :old.can_id=r.can_id;
end tvc ;
/* This are the table's used */
create table candidate(
can_id number(8),
name varchar(256),
age number(3) check (age>=18),
gender varchar(7),
aff_party varchar(256),
seat_no number(5),
seat_name varchar(256),
net_income number(8),
primary key(can_id)
);
create table cast_vote(
vote_no number(15) not null,
voter_id number(8) not null unique,
can_id number(8),
primary key(vote_no),
foreign key (voter_id) references voter(voter_id),
foreign key(can_id) references candidate(can_id)
);
create table results (
can_id number(10) primary key,
total_vote number(10),
foreign key (can_id) references candidate(can_id)
);
/ 我希望触发器起作用 /
答案 0 :(得分:0)
尝试一下,它应该可以工作
CREATE OR REPLACE TRIGGER tvc
AFTER INSERT ON cast_vote
REFERENCING NEW AS newRow OLD AS oldRow
FOR EACH ROW
BEGIN
UPDATE results SET total_vote =(select max(total_vote) from results where
can_id=:newRow.can_id)+1 where
can_id=:newRow.can_id;
END tvc;
编辑:
此外,如果RESULTS
表中最初没有行,它将处理
CREATE OR REPLACE TRIGGER tvc
AFTER INSERT ON cast_vote
REFERENCING NEW AS newRow OLD AS oldRow
FOR EACH ROW
DECLARE
initialcnt number;
BEGIN
SELECT COUNT(*) INTO initialcnt FROM results;
IF(initialcnt=0) THEN
INSERT INTO results VALUES(:newRow.can_id,1);
ELSE
UPDATE results SET total_vote =(select max(total_vote) from
results where can_id=:newRow.can_id)+1 where can_id=:newRow.can_id;
END tvc;
答案 1 :(得分:0)
最初,RESULTS
表中没有行,因此没有要更新的内容;首先插入一行。
SQL> create table cast_vote(
2 vote_no number(15) not null,
3 voter_id number(8) not null unique,
4 can_id number(8),
5 primary key(vote_no)
6 );
Table created.
SQL> create table results (
2 can_id number(10) primary key,
3 total_vote number(10)
4 );
Table created.
SQL> create or replace Trigger tvc
2 before insert on cast_vote
3 for each row
4 begin
5 update results r set
6 r.total_vote = r.total_vote + 1
7 where r.can_id = :new.can_id;
8
9 if sql%rowcount = 0 then
10 -- the first row for CAN_ID - insert
11 insert into results (can_id, total_vote)
12 values (:new.can_id, 1);
13 end if;
14 end tvc ;
15 /
Trigger created.
测试:
SQL> insert into cast_vote (vote_no, voter_id, can_id) values (1000, 1, 200);
1 row created.
SQL> insert into cast_vote (vote_no, voter_id, can_id) values (1001, 2, 200);
1 row created.
SQL> select * From cast_Vote;
VOTE_NO VOTER_ID CAN_ID
---------- ---------- ----------
1000 1 200
1001 2 200
SQL> select * From results;
CAN_ID TOTAL_VOTE
---------- ----------
200 2
SQL>
答案 2 :(得分:-1)
如果“所有候选人的总票数从零开始”意味着每个候选人都有一行,其票数最初定义为0,那么以下工作(几乎是您的工作):
1.删除声明,则不必要,也可以将其反转并“针对每一行”。
2.更改:old.can_id = r.can_id;到:new.can_id = r.can_id;在插入触发器中:old不存在(您可以引用它,但所有列均为空)。
如果总票数可能没有初始化,请使用合并。
create or replace Trigger tvc
before insert
on cast_vote
for each row
begin
merge into results r
using (select :new.can_id newid from dual)
on (newid = r.id)
when matched then
update set total_vote = total_vote+1
when not matched then
insert (id,total_vote) values(newid,1);
end tvc;