Как обновить значение другой таблицы, используя триггер вставки другой таблицы - PullRequest
0 голосов
/ 21 июня 2019

Я работаю над проектом базы данных по национальной избирательной системе.При голосовании за определенного кандидата я хочу автоматически обновить 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)
    );

/ Я хочу, чтобы триггер работал /

Ответы [ 3 ]

0 голосов
/ 21 июня 2019

Изначально в таблице 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>
0 голосов
/ 21 июня 2019

Если «total_votes всех кандидатов инициируется с нуля» означает, что для каждого кандидата с изначально определенным подсчетом 0 голосов есть строка, то работают следующие (почти то, что вы имели):
1. Удалить объявление, в этом нет необходимости, или поменяйте его местами и «для каждого ряда».
2. изменить: old.can_id = r.can_id; to: new.can_id = r.can_id; В триггере вставки: старый не существует (вы можете сослаться на него, но все столбцы нулевые).
Если существует вероятность того, что общее количество голосов не было инициализировано, используйте Merge.

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;
0 голосов
/ 21 июня 2019

Попробуйте, это должно работать

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...