trigger: moving date from 1 table to another - mysql

here is my code:
create trigger term_ost after update on `payments`
for each row
begin
UPDATE `current` s
INNER JOIN payments w ON w.id_thing = s.id_thing
INNER JOIN payments w ON w.id= s.id
SET s.`new_pay_date` = w.date;
end;
$$
It's not working.
I want it to set new date after there is new payment for thing which someone bought and change the last date that was in the field date with the new one from new_pay_date.
#EDIT
I am trying to change my trigger so it will update field "new_pay_date" from current after field date is insterted into payments.
Table current:
curr_cash
new_pay_date
id_person
id_thing
sum_of_things
Summary:
When I add new data to payments (e.x. someone paid for thing), I want ot update his last payment time in table current. In "sum_of_things" it sums all the money the client paied.
#edit
After this code:
CREATE TRIGGER term_ost AFTER INSERT ON `payments`
FOR EACH ROW
BEGIN
UPDATE `current`
SET s.`new_pay_date` = NEW.date
WHERE
s.id_thing = NEW.id
END;
there is error:
INSERT INTO `mydb`.`payments` (
`id` ,
`date` ,
`id_thing` ,
`thing_cost`
)
VALUES (
'12312312322', '2012-12-11 15:00:00', '1', '500'
)
MySQL comment:
#1054 - Unknown column 's.new_pay_date' in 'field list'
... :-(

You are using the same table alias w multiple times and that is not allowed. Seems you want to join on multiple columns:
CREATE TRIGGER term_ost AFTER INSERT ON `payments`
FOR EACH ROW
BEGIN
UPDATE `current`
SET `new_pay_date` = NEW.date
WHERE
id_thing = NEW.id
END;

Related

How to use an IF statement in a MYSQL Trigger?

Trying to create a trigger that will look for two conditions and update an audit table with those. The trigger works on a customers table and looks for an update to phone number and/or credit limit. The audit table will have a column that show's which field was update or if both were updated.
Here's what I have so far (update with code from below) same error:
#Here's the audit table I created:
create table cust_audit(customerNumber INT, customerName varchar(50),
phone varchar(50), creditLimit dec(10,2),
last_update timestamp, `user` varchar(30),
row_value varchar(20), fields_changed,
varchar(30));
Delimiter $$
CREATE TRIGGER cust_upd_old
AFTER UPDATE
ON customers
FOR EACH ROW
Begin
INSERT INTO audit_table(customerNumber,
customerName,
phone,
creditLimit,
last_update,
`user`,
row_value,
fields_changed)
VALUES (OLD.customerNumber,
OLD.customerName,
OLD.phone,
OLD.creditLimit,
now(),
current_user(),
'before update',
CASE WHEN NEW.phone = OLD.phone THEN 'creditLimit'
WHEN NEW.creditLimit = OLD.creditLimit THEN 'phone number'
ELSE 'both'END);
END $$
DELIMITER ;
The trigger will run but when I try to run an update statement the update fails with code Error Code: 1054. Unknown column 'customerNumber' in 'field list' but the select statement will work so it's some error with the trigger I think. USING MYSQL 8.0.21
update customers set phone = '2128822470' where customerNumber = 181;
select * from customers where customerNumber = 181;
Can be simplified to
CREATE TRIGGER cust_upd_old
AFTER UPDATE
ON customers
FOR EACH ROW
INSERT INTO audit_table(customerNumber,
customerName,
phone,
creditLimit,
last_update,
`user`,
row_value,
fields_changed)
VALUES (OLD.customerNumber,
OLD.customerName,
OLD.phone,
OLD.creditLimit,
now(),
current_user(),
'before update',
CASE WHEN NEW.phone = OLD.phone THEN 'creditLimit'
WHEN NEW.creditLimit = OLD.creditLimit 'phone number'
ELSE 'both' END);

MySQL Trigger: update record in one table where record in the same row match select query

new to MySQL and databases and need some help.
I have the tables:
appointment
appointment_id int PK , <-
patient_id int ,
doctor_id int , <-
appointment_time DateTime.
queue
appointment_id int PK, <-
actual_time DateTime.
queue_summary
date datetime ,
doctor_id int PK , <-
num_of_patients int. <-
I need to write a trigger that will update the num_of_patients by adding +1 to the record in the row that the doctor_id in the queue_summary is overlapping with the new row inserted into queue that corresponds to the appointment (to extract the doctor_id).
ex. in case of insertion to queue:
appointment table status:
need to update:
I wrote the following select query to extract the doctor_id that was affected by the insertion/deletion to queue:
select appointment.doctor_id
from appointment as a
join queue as q
on a.appointment_id = q.appointment_id
where new.appointment_id = a.appointment_id;
and I tried to write the trigger as followed:
delimiter //
CREATE TRIGGER tr_insert
BEFORE INSERT ON queue
FOR EACH ROW
BEGIN
set queue_summary.num_of_patients = queue_summary.num_of_patients+1
where queue_summary.doctor_id = (
select appointment.doctor_id
from appointment as a
join queue as q
on a.appointment_id = q.appointment_id
where new.appointment_id = a.appointment_id
)
END;//
delimiter ;
But with no luck...
I know I have some syntax error in the where part but I can't manage it to work...
please advise,
thanks in advance!
The SET command inside triggers can only be used on NEW var, which points to the row that is being processed. To update another table, you need to issue a normal UPDATE command:
delimiter //
CREATE TRIGGER tr_insert
BEFORE INSERT ON queue
FOR EACH ROW
BEGIN
update queue_summary
set queue_summary.num_of_patients = queue_summary.num_of_patients+1
where queue_summary.doctor_id = (
select appointment.doctor_id
from appointment as a
join queue as q
on a.appointment_id = q.appointment_id
where new.appointment_id = a.appointment_id
)
END;//
delimiter ;
Thats the reason why appers a syntax error on where, it's because mysql set command wont expect it there, SET only accepts var name and value.

Summing the values from the 2nd table based on ID of the 1st table and inserting values in first table

How to in first table where it says UkupnaCena insert sum value of column Cena where RacunID in first table is equal to RacunID in other table. For example if RacunID is equal to 1 in first table, I want its UkupnaCena to be equal to sum of all values in column Cena where RacunID is 1.
Tables:
My procedure so far:
Create procedure sp_RacunUpdate(
#pRacunID int,
#pStatusRacuna nvarchar(50),
#pDatum nvarchar(20),
#pOpis nvarchar(200),
#pMesto nvarchar(50),
#pKupacID int
)
as begin
Declare #pUkupnaCena decimal(20,2)
select #pUkupnaCena=sum(Cena) from Stavka
inner join Racun
on Racun.RacunID=Stavka.RacunID
Where Racun.RacunID=Stavka.RacunID
group by Stavka.RacunID
begin transaction
UPDATE Racun
SET StatusRacuna=#pStatusRacuna, Datum=#pDatum, Opis=#pOpis,Mesto=#pMesto,UkupnaCena=#pUkupnaCena,KupacID=#pKupacID
WHERE RacunID=#pRacunID
IF ##ERROR <> 0
BEGIN
ROLLBACK
END
ELSE
BEGIN
COMMIT
END
END
GO
You can modify the update query to something like this
UPDATE Racun from Racun
SET UkupnaCena=(select sum(Cena) from Stavka s where s.RacunID= Racun.RacunID), Datum=#pDatum, Opis=#pOpis,Mesto=#pMesto,KupacID=#pKupacID
WHERE RacunID=#pRacunID
I believe you want a correlated subquery. In MySQL, this would look like:
UPDATE Racun r
SET StatusRacuna = #pStatusRacuna,
Datum = #pDatum,
Opis = #pOpis,
Mesto = #pMesto,
KupacID = #pKupacID,
UkupnaCena = (SELECT SUM(s.Cena) FROM Stavka s WHERE s.RacunID = r.RacunId)
WHERE RacunID = #pRacunID;
However, your code does not look like MySQL; it looks more like SQL Server. In either database, you can do:
UPDATE Racun
SET StatusRacuna = #pStatusRacuna,
Datum = #pDatum,
Opis = #pOpis,
Mesto = #pMesto,
KupacID = #pKupacID,
UkupnaCena = (SELECT SUM(s.Cena) FROM Stavka s WHERE s.RacunID = Racun.RacunId)
WHERE RacunID = #pRacunID;
The only difference here is removing the table alias in the outer query.

MySQL procedure returning wrong value (INSERT SELECT confronting)

I'm completely new to MySQL, and have been bumping with some errors, but always I do find solutions, except for this one I can't understand how to get around it.
The following MySQL Procedure returns me a value if variable "ue" is 1 or 0 (a bunch of exists validation). The validation part (SET ue = EXISTS...) works without the rest of the code, as it should, the problem is not there. But when I do execute the command INSERT INTO SELECT, it does not work, it always return 0 as response, when it should be 1. These two lines are getting in confrontation with each other.
INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1;
SELECT ue AS response;
The procedure should add 'user id' and 'event id' into meetup_participation, and then update the row at 'users' corresponding to the user with that 'user id' to increment the 'events participated'. And it also UPDATE to increment the participation in the event with this 'event id'.
I am using the SET ue to validate things like, if user exists, if event does exists, if date of event is still valid, and if user is not already in this table. So I am passing this value as a boolean to INSERT INTO meetup_participation [...] WHERE ue = 1. After that, I do SELECT ue to inform validation returned true and procedure executed without problems.
Here is the full procedure.
CREATE DEFINER=`user`#`localhost` PROCEDURE `join_event`(IN `user_id` BIGINT(64), IN `event_id` INT) NOT DETERMINISTIC MODIFIES SQL DATA SQL SECURITY DEFINER
begin
DECLARE ue INT;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) AND EXISTS(SELECT 1 FROM meetup WHERE date > NOW() AND meet_id = event_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND participants <= max_participants) AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id);
INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1;
UPDATE users SET events_participated = events_participated + 1 WHERE fb_uid=user_id AND ue=1;
UPDATE meetup SET participants = participants + 1 WHERE meet_id=event_id AND ue=1;
SELECT ue AS response;
end
Thanks in advance.
The INSERT statement is executed separately from the SET ue =... statement. I'm not sure what you are trying to accomplish, but the code makes no sense.
If you want to add records to meetup_participation based on the EXISTS tests applied to each record in the users table, you would need to apply the tests to each record in your SELECT statement as part of the INSERT.
There are also numerous syntax/grammar issues in the code as shown.
If you could provide an explanation of what you are trying to accomplish with the procedure, that might allow someone to suggest the right way to code the procedure.
Selecting ue will not tell you if the procedure completed without error. You should research mysql transactions and mysql error handling. http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ is a good starting point.
You might end up with something like this
drop procedure if exists p;
delimiter //
CREATE DEFINER=`root`#`localhost` PROCEDURE `p`(
IN `inue` int,
IN `user_id` BIGINT(64),
IN `event_id` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''
begin
DECLARE ue INT;
declare exit handler for sqlexception
begin
rollback;
insert into errors (msg) select concat('error ' ,inue,',',user_id,',',event_id);
end;
set autocommit = 0;
#set ue = inue;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id)
AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id)
#AND EXISTS(SELECT 1 FROM meetup WHERE dt > NOW() AND meet_id = event_id)
AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND ifnull(participants,0) <= max_participants)
AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id)
;
select ue;
if ue = 1 then
start transaction;
INSERT INTO meetup_participation SELECT user_id, event_id,user_id, event_id;
UPDATE users SET events_participated = ifnull(events_participated,0) + 1 WHERE fb_uid=user_id = user_id;
UPDATE meetup SET participants = ifnull(participants,0) + 1 WHERE meet_id = event_id ;
commit;
end if;
SELECT ue AS response;
end //
The error table looks like this
CREATE TABLE `errors` (
`msg` varchar(2000) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
Note I am not suggesting this is a solution appropriate to your site , you need to do the research and figure out what is best for you.

Compare two values from different tables - MySql

I need to check before insert into 'year' column of ( Academic Report) that it's not less than the year of 'enrollment date' column in (student)
my tables :
CREATE TABLE STUDENT
(
BCN INT (10) ,
Enrollment_Date timestamp not null default CURRENT_TIMESTAMP,
primary key (BCN),
);
CREATE TABLE ACADEMIC_REPORT
(
Stud_Num INT(10) ,
Year year ,
primary key (Stud_Num , Year ),
foreign key (Stud_Num ) references STUDENT( BCN )
ON DELETE restrict ON UPDATE CASCADE
);
I've try this :
/* ACADEMIC_REPORT._Year Constraint "BEFORE INSERT" */
delimiter //
CREATE TRIGGER ReportYearBIN BEFORE INSERT ON ACADEMIC_REPORT
FOR EACH ROW
BEGIN
declare num int(10);
SET num= (SELECT BCN
FROM STUDENT , ACADEMIC_REPORT
WHERE BCN = ACADEMIC_REPORT.Stud_Num );
IF (ACADEMIC_REPORT.Year < YEAR(num.Enrollment_Date))
THEN
SIGNAL SQLSTATE '10000'
SET MESSAGE_TEXT = 'Error....!';
END IF;
END;
// delimiter ;
but it causes this error during insert
Error Code: 1054. Unknown column 'ACADEMIC_REPORT.Year' in 'field list'
How can I do that constraint ?
Using MySql workbench 6.3
Thank you in advance.
Okay, I created a select statement for the conditions that you want to generate the error on. If the student exists for this report and the report year is less than the students enrollment date it will generate one or more rows for the select query. The proceeding FOUND_ROWS() will then be greater than 0 which will trigger your error message.
CREATE TRIGGER ReportYearBIN BEFORE INSERT ON ACADEMIC_REPORT
FOR EACH ROW
BEGIN
SELECT * FROM STUDENT WHERE BCN=new.Stud_Num AND new._year < Enrollment_Date
IF (SELECT FOUND_ROWS() > 0)
THEN
SIGNAL SQLSTATE '10000'
SET MESSAGE_TEXT = 'Error....!';
END IF;
END;
I've figured out the problem :)
This statement is completely wrong,
YEAR(num.Enrollment_Date)
because it's not correct to write attribute.attribute, you can only use Table.Attribute.
So, here is the solution
/* ACADEMIC_REPORT._Year Constraint "BEFORE INSERT" */
delimiter //
CREATE TRIGGER ReportYearBIN BEFORE INSERT ON ACADEMIC_REPORT
FOR EACH ROW
BEGIN
declare Enroll timestamp;
SET Enroll = (SELECT Enrollment_Date
FROM STUDENT
WHERE BCN = new.Stud_Num);
IF ( new._year < YEAR(Enroll))
THEN
SIGNAL SQLSTATE '10000'
SET MESSAGE_TEXT = 'Error..The Report year cannot be less than the enrollment year..!';
END IF;
END;
// delimiter ;