MySQL : Trigger Syntax not correct - mysql

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

Related

MySQL Trigger IF syntax error

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 ;

I want that the studentid table field with zreo value is not insert,i do this by using trigger but it still allow to insert them

Still allow insert zero value..
CREATE TRIGGER check_my_constraint BEFORE insert ON `personal_details`
FOR EACH ROW
BEGIN
DECLARE msg varchar(255);
IF (NEW.studentid<0)
THEN
SET msg = concat('Constraint my_constraint violated: studentid must not be zero ', cast(new.studentid as char));
SIGNAL sqlstate '45000' SET message_text = msg;
END IF;
END ;
You only check for less than zero. You will have to check for less than or equal to zero:
IF (NEW.studentid <= 0)
Change the condition -
IF (NEW.studentid<0) => IF (NEW.studentid <= 0)

SQL duplicate trigger

I have simple project for database classes there i have shop database which implement such logic: for each customer in order table we have order with type = 'CART' when customer confirm his order his order change it type to 'ORDER' and we create a new CART for our customer.
Now i want to write trigger that allows me to control that each customer has only one CART.
I write something like this
DELIMITER $$
USE `newshop`$$
CREATE
DEFINER=`root`#`localhost`
TRIGGER `newshop`.`cart_check`
BEFORE INSERT ON `newshop`.`order`
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
DECLARE count_pn INTEGER;
SELECT count(*) INTO count_pn FROM newshop.order
where newshop.order.type = NEW.type
and NEW.user_id = newshop.order.user_id
and NEW.type = 'CART'
or NEW.type = 'cart'
LIMIT 1;
if count_pn > 0 THEN
BEGIN
set msg = 'Oh no';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
end;
ELSE
BEGIN
set msg = 'Oh yeah';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END;
END IF;
END$$
then when i try to insert into table new order with type cart for user with id = 1, that already has a cart - this trigger doesn't allow me to do this and if i try to add a cart for another user, that doesn't have cart - this trigger also doesn't allow me to do this.
In else, you also have the SIGNAL SQLSTATE=45000, which is unhandled exception, it will cause return as failed.
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;

Mysql Prevent insert with insert trigger condition not met

I am trying to setup a trigger so an insert does not occur if a condition is not met.
I thought the below was the way to do it but i am not sure
I am getting an error
/* SQL Error (1407): Bad SQLSTATE: '45000 ' */
Can anyone let me know why I am getting this error and the best way for me to prevent an insert if the condition is not met in mysql.
DELIMITER $$
SHOW WARNINGS$$
USE `warrington_central`$$
CREATE TRIGGER before_insert_image_comment_section_check
BEFORE INSERT ON image_comment FOR EACH ROW
BEGIN
DECLARE error_msg varchar(255);
IF New.section != (SELECT id from section where section = "image")
THEN SET error_msg = "Cannot insert a comment into this section as it is the wrong section type";
SIGNAL SQLSTATE '45000 'SET MESSAGE_TEXT = error_msg;
END IF;
END
$$
SHOW WARNINGS$$
SQLSTATE is required to be a a 5 character string unless previously declared using DECLARE ... CONDITION;
SIGNAL SQLSTATE '45000 'SET MESSAGE_TEXT = error_msg;
You're trying to set SQLSTATE to '45000 ' (note the space) which is 6 characters long. Fix the spacing and you should not see the message again (it is also reflected in your error message, but the space is a bit hard to see)

MySQL trigger definition - 1064 error

My proposed trigger:
#START TRIGGER
delimiter //
DECLARE msg VARCHAR(255);
CREATE TRIGGER passStandard_check BEFORE INSERT ON Module
FOR EACH ROW
BEGIN
IF NEW.passStandard < 0 || NEW.passStandard > 1 THEN
set msg = concat('Trigger Error: Pass Standard: ', cast(NEW.passStandard as char));
signal sqlstate '45000' set message_text = msg;
END
//
delimiter ;
#END TRIGGER
But I get the following error:
Error Code: 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 'DECLARE msg VARCHAR(255); CREATE TRIGGER passStandard_check BEFORE INSERT ON Mod' at line 1
Adding in END IF does not make any difference.
passStandard is set to an INT NOT NULL.
Edit
I've moved the DECLARE statement after the BEGIN:
#START TRIGGER
delimiter //
CREATE TRIGGER passStandard_check BEFORE INSERT ON Module
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
IF NEW.passStandard < 0 || NEW.passStandard > 1 THEN
set msg = concat('Trigger Error: Pass Standard: ', cast(NEW.passStandard as char));
signal sqlstate '45000' set message_text = msg;
END IF;
END
//
delimiter ;
#END TRIGGER
But I still get this error:
Error Code: 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 'sqlstate '45000' set message_text = msg; END IF; END' at line 7
You need to declare your variable "msg" inside your procedure and use END IF
#START TRIGGER
delimiter //
CREATE TRIGGER passStandard_check BEFORE INSERT ON Module
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255); /* << PUT THIS HERE */
IF NEW.passStandard < 0 || NEW.passStandard > 1 THEN
set msg = concat('Trigger Error: Pass Standard: ', cast(NEW.passStandard as char));
signal sqlstate '45000' set message_text = msg;
END IF; /* << YOU WILL NEED THIS TOO (DONT FORGET THE SEMICOLON :D) */
END//
delimiter ;
#END TRIGGER
I noticed that I was getting MySQL warnings when adding triggers with IF/ELSE logic in them if I wasn't adding parentheses to the IF statements. Not sure why, but I added the brackets and the warnings went away. Try something like:
IF ((NEW.passStandard < 0) || (NEW.passStandard > 1)) THEN
set msg = concat('Trigger Error: Pass Standard: ', cast(NEW.passStandard as char));
signal sqlstate '45000' set message_text = msg;
END IF;
Try breaking it up to several queries. Or run it in phpmyadmin which handles semi colon separated multi queries.
Might be this:
DECLARE is permitted only inside a BEGIN ... END compound statement and must be at its start, before any other statements.
http://dev.mysql.com/doc/refman/5.0/en/declare.html
i got it working. pls find below the working code.
delimiter //
CREATE TRIGGER test_check1 BEFORE INSERT ON employee
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
IF (NEW.sync_id = '0') THEN
SET NEW.name = 'Collect Money';
signal sqlstate '45000' set message_text = msg;
END IF;
END//
delimiter ;