I was creating some triggers (using MySQL Workbench), and got an error regarding the if statement in one of them. Here it is:
CREATE DEFINER = CURRENT_USER TRIGGER `mydatabase`.`transactions_AFTER_UPDATE` AFTER UPDATE ON `transactions` FOR EACH ROW
begin
if (old.idUser != new.idUser) then
signal sqlstate '45000' set message_text = "Can't change transactions' initiator.";
end if;
declare oldAmountTokens integer;
SET #oldAmountTokens = (SELECT tokens from offers WHERE idoffer = old.idOffer);
declare newAmountTokens integer;
SET #newAmountTokens = (SELECT tokens from offers WHERE idoffer = new.idOffer);
declare diff integer;
SET #diff = #newAmountTokens - #oldAmountTokens;
UPDATE users SET tokens = users.tokens + #diff WHERE idUser = new.idUser;
end
MySQL Workbench tells me
"missing 'end'" at line 6 (where the 'end if;' is),
and phpMyAdmin tells me
"#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5".
I'm really stuck on this, so I'd be really happy if someone could help me, I've searched for the IF syntax on the web, but I don't see anything wrong...
Okay, problem solved.
First, I needed to use delimiters to avoid the error near end if;.
For the next error, MySQL requires declare statements to be put next to the begin, thanks to this post I found the answer. Thanks !
Your trigger code looks okay to me, although I am removing the single quote after transactions. Do you have delimiter statements?
delimiter //
CREATE DEFINER = CURRENT_USER TRIGGER `mydatabase`.`transactions_AFTER_UPDATE`
AFTER UPDATE ON `transactions` FOR EACH ROW
begin
if (old.idUser <> new.idUser) then
signal sqlstate '45000' set message_text = "Can't change transactions initiator.";
end if;
declare #oldAmountTokens integer;
SET #oldAmountTokens = (SELECT tokens from offers WHERE idoffer = old.idOffer);
declare #newAmountTokens integer;
SET #newAmountTokens = (SELECT tokens from offers WHERE idoffer = new.idOffer);
declare #diff integer;
SET #diff = #newAmountTokens - #oldAmountTokens;
UPDATE users SET tokens = users.tokens + #diff WHERE idUser = new.idUser;
end//
delimiter ;
Related
I'm trying to create a SQL Trigger, but i receive always an error message, i want to check on update and insert operation if value called status is not higher than 1 and not lower than 0.
CREATE TRIGGER tr_ins_cert_login
BEFORE UPDATE ON cert_login
FOR EACH ROW
BEGIN
DECLARE errorMessage VARCHAR(255);
SET errorMessage('Invalid Status Value.');
IF new.status <> 0 AND new.status <> 1 THEN
SET MESSAGE_TEXT = errorMessage;
END IF;
END
When i try to run the commands it returns error.
I'm using MySql.
The error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5
Any hint?
Message_text should be part of signal sqlstate following syntaxes on my box
drop trigger if exists t;
delimiter $$
CREATE TRIGGER t
BEFORE UPDATE ON cert_login
FOR EACH ROW
BEGIN
DECLARE errorMessage VARCHAR(255);
SET errorMessage = ('Invalid Status Value.');
IF new.status <> 0 AND new.status <> 1 THEN
SIGNAL SQLSTATE '01000'
SET MESSAGE_TEXT = errorMessage;
END IF;
END $$
delimiter ;
and https://www.db-fiddle.com/f/913nweKrHqXL5SViuuqAZE/0
ps your first set statement is invalid you missed the =
Upon creating a trigger i get the following error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
This is my query:
CREATE TRIGGER reserved BEFORE INSERT ON Reserv
FOR EACH ROW BEGIN
DECLARE trip_id integer;
DECLARE free integer;
DECLARE count integer;
set #free := (select place_free from Trips where id = trip_id);
set #count := (select count from inserted);
if #count <= #free
begin
update Trips set place_free = #free - #count where id = #trip_id;
end
ELSE
BEGIN
ROLLBACK;
return;
END
END
What I see is that you are using the RETURN statement. As https://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html#stored-routines-trigger-restrictions states:
The RETURN statement is not permitted in triggers, which cannot return
a value. To exit a trigger immediately, use the LEAVE statement.
But from my point of view this is a different topic, as the error message speaks of a syntax error in line 3. Maybe you forgot to set the delimiter to something different than ;:
DELIMITER //
CREATE TRIGGER ...
DELIMITER ##
create trigger tra_Price after update on assets_cdn_charge for each row
begin
declare res int;
declare ids int;
declare idq int;
declare idt int;
set res = (select price from assets_cdn_charge where price = new.price);
set ids = (select id from assets_cdn_charge where price = new.price);
DECLARE cur CURSOR FOR SELECT id FROM assets_cdn_composite WHERE cdn_charge_id = ids;
open cur;
ins_loop:LOOP
fetch cur into idq;
declare curs cursor for select id from assets_cdn_traffic where domain_name_id = idq;
open curs;
ins1_loop:LOOP
fetch curs into idt;
update assets_cdn_traffic set cost = traffic * res where domain_namd_id = idt;
end LOOP;
close curs;
end LOOP;
close cur;
END; ##
when I run this code,I had get this error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'DECLARE cur CURSOR FOR SELECT id FROM
assets_cdn_composite WHERE cdn_charge_id =' at line 9
Probably because:
DECLARE is permitted only inside a BEGIN ... END compound statement
and must be at its start, before any other statements.
...so that line should likely be moved before the two set statements above that point.
I believe that you're going to have other trouble if that fixes that error, because I don't know what you expect that query to retrieve as idq is declared before that point, but is not set to any value?
=====
UPDATE:
Below is an example from a previous comment about the possibility to eliminate cursors altogether. Try this:
BEGIN
UPDATE assets_cdn_traffic
JOIN assets_cdn_composite ON assets_cdn_traffic.domain_name_id = assets_cdn_composite.cdn_charge_id
JOIN assets_cdn_charge ON assets_cdn_charge.id = assets_cdn_composite.cdn_charge_id
SET cost = traffic * NEW.price
WHERE assets_cdn_charge.id = NEW.id
END
However, I would try the update query separately before using in the trigger to make sure that it works as expected. Replace the NEW.price and the NEW.id with test values to verify the handling.
I want to make a trigger that prevent inserting overlaping dates. For example:
If I have an offer "Oferta" with the date from 1/3/2016 to 5/3/2016, I can't insert a new offer with the date 2/3/2016 to 4/3/2016 or 4/3/2016 to 7/3/2016
My SELECT checks that condition I believe. What I don't know how to do is to make an error if such happens. I'm new to triggers and Im having syntax errors, I checked triggers syntax but couldnt find the problem...
DELIMITER $$
CREATE TRIGGER tri_check_date_overlap BEFORE INSERT ON Oferta
FOR EACH ROW
BEGIN
IF EXISTS(
SELECT * FROM Oferta WHERE
(new.morada = morada AND new.codigo = codigo
AND ((new.data_inicio BETWEEN data_inicio AND data_fim)
OR new.data_fim BETWEEN data_inicio AND data_fim)
)
)
/*CALL raise_application_error(3001, 'Not odd number!'); */
DECLARE msg varchar(255);
set msg = concat('Error: That right is not allowed!', cast(new.right as char));
signal sqlstate '45000' set message_text = msg;
END $$
DELIMITER ;
Your logic is ok, I think you just missed the 'then' condition after 'if' and 'end if' before the end of the trigger.
I'm trying to write a trigger for a table named classes_tbl where I basically want to check before update if the participants are at the maximum, if true - do not allow update, and raise error message.
As well as check if participants = 0 in case the the update table tries to decrease the number, it needs not to be possible to decrease below 0 - and again raise an error message in this case.
I'm not 100% accustomed to MySQL so I'm not sure what is missing or wrong. It would be nice If someone could give me a hint.
Here is my Create Trigger syntax:
DELIMITER //
CREATE TRIGGER MaxBelegt_TRGGR
BEFORE UPDATE ON classes_tbl
FOR EACH ROW
BEGIN
DECLARE
n_count NUMBER(3);
msg varchar(255);
SELECT maxParticipants
INTO n_count
FROM rooms_tbl
WHERE rid = :NEW.rid;
IF :OLD.participants = n_count THEN
set msg = concat('MyTriggerError: MaxParticipants for Room exceeded. On MaxBelegt_TRGGR -> belegtAnz : ', cast(OLD.participants as char));
signal sqlstate '45000' set message_text = msg;
END IF;
IF :NEW.participants < 0 THEN
set msg = concat('MyTriggerError: Participant number already 0. On MaxBelegt_TRGGR -> belegtAnz : ', cast(OLD.participants as char));
signal sqlstate '45000' set message_text = msg;
END IF;
END
//
DELIMITER;
Thank You!
BTW: I'm using mysql version : 5.6.24 .. just in case