Can i use nested BEGIN/END blocks in Triggers (mySQL) - mysql

I would like to know why my code is not working. The ideia is to verify that when a idseq is added to a certain table, to see if that same idseq already exists in any other table.
The following code produces ERROR 1235 in mySQL:
delimiter //
CREATE TRIGGER trigger_pagina
BEFORE INSERT ON pagina
FOR EACH ROW
BEGIN
IF (EXISTS(
SELECT R.idseq
FROM registo R
WHERE (NEW.idseq = R.idseq)
) )THEN
CALL Ilegal_Insert();
END IF;
END;
BEGIN
IF (EXISTS(
SELECT T.idseq
FROM tipo_registo T
WHERE (NEW.idseq = T.idseq)
)) THEN
CALL Ilegal_Insert();
END IF;
END;
BEGIN
IF (EXISTS(
SELECT V.idseq
FROM valor V
WHERE (NEW.idseq = V.idseq)
)) THEN
CALL Ilegal_Insert();
END IF;
END;
BEGIN
IF (EXISTS(
SELECT C.idseq
FROM campo C
WHERE (NEW.idseq = C.idseq)
)) THEN
CALL Ilegal_Insert();
END IF;
END;//
delimiter ;
Thanks in advance !

You need another, outermost BEGIN ... END block to enclose the ones you have above, like
delimiter //
CREATE TRIGGER trigger_pagina
BEFORE INSERT ON pagina
FOR EACH ROW
BEGIN -- Add a BEGIN here...
BEGIN
IF (EXISTS(
...
END IF;
END;
BEGIN
...
END;
END; -- and an END here
//
delimiter ;
This is because CREATE TRIGGER actually only allows the trigger body to contain a single statement, and BEGIN ... END is treated, along with its contents, as a single statement.
So yes, you can (and in this case must) use nested BEGIN ... END blocks in a trigger body.

Related

My Procedure for checking login Credentials is given below it gives error pls give solution

DELIMITER $$
USE `skilltest`$$
CREATE PROCEDURE Validate_User1($Username NVARCHAR(20), $_Password NVARCHAR(20))
BEGIN
DECLARE $UserId INT;DECLARE $LastLoginDate DATETIME;
IF EXISTS(SELECT (Username) FROM Users WHERE Username=$Username)
THEN
BEGIN
IF EXISTS(SELECT * FROM Users WHERE Username=$Username AND _Password=$_Password)
THEN
BEGIN
SELECT -1 -- UserValidate
END$$
ELSE
BEGIN
SELECT -2 -- Password Wrong
END$$
END$$
ELSE
BEGIN
SELECT -3 -- USERNAME DOES NOT EXIST
END$$
END$$
DELIMITER ;
Assuming this is mysql (there are elements in the code which suggest sql server) every statement must terminate with ; , a comment should be preceeded by # (not --), every if must have a matching end if; , begin..end blocks are not required in the if...endif blocks, only one else is allowed per if, every begin must have a matching end;
, only 1 end $$ is required. Although not required syntactically indenting your code makes it much more readable for us humans.
The following at least syntaxes
DROP PROCEDURE IF EXISTS Validate_User1;
DELIMITER $$
CREATE PROCEDURE Validate_User1($Username NVARCHAR(20), $_Password NVARCHAR(20))
BEGIN
DECLARE $UserId INT;DECLARE $LastLoginDate DATE;
IF EXISTS(SELECT Username FROM Users WHERE Username=$Username) THEN
IF EXISTS(SELECT * FROM Users WHERE Username=$Username AND _Password=$_Password) THEN
SELECT -1; #UserValidate
ELSE
SELECT -2; #Password Wrong
END IF;
ELSE
SELECT -3; #USERNAME DOES NOT EXIST
END IF;
END $$
DELIMITER ;

Trigger to change empty values to NULL

I am trying to write a trigger where if an incoming value is empty (in other words ''), then insert NULL in the table. I have :
DELIMITER //
CREATE TRIGGER avoid_empty
BEFORE INSERT ON EVALUATION
FOR EACH ROW
BEGIN
IF mark = '' THEN SET NEW.mark = NULL;
END IF;
END;
//
DELIMITER ;
Which executes without errors, but it doesn't do what I need.
Try:
DELIMITER //
CREATE TRIGGER `avoid_empty` BEFORE INSERT ON `EVALUATION`
FOR EACH ROW
BEGIN
IF NEW.`mark` = '' THEN
SET NEW.`mark` := NULL;
END IF;
END//
DELIMITER ;
See db-fiddle.

MySQL need help setting up trigger

I am trying to set up a TRIGGER to clear empty strings before INSERT. Not rocket science but I can't find the error in my syntax!
Here is the TRIGGER itself
USE `ga_abtest_logging`;
DELIMITER $$
CREATE TRIGGER avoid_empty
BEFORE INSERT ON daily_analytics
FOR EACH ROW
BEGIN
IF profileID = ''
THEN SET profileID = NULL
END IF;
END$$
Here is what workbench is showing:
On hover over the END IF it reads syntax error, unexpected END, expecting ';'
Could I have a problem with the settings on my DB? I have gone through the MySQL docs and I think the trigger looks right! Does anyone see anything obviously wrong?
You should make a few changes:
Use the NEW. prefix when referencing a column value
Add a semi-colon at the end of the line where you set the value
For example:
DELIMITER $$
CREATE TRIGGER tr_b_ins_daily_analytics BEFORE INSERT ON daily_analytics FOR EACH ROW BEGIN
IF (NEW.profileID = '')
THEN
SET NEW.profileID = NULL;
END IF;
END $$
DELIMITER ;
The code below should work.
DELIMITER $$
CREATE TRIGGER avoid_empty
BEFORE INSERT ON daily_analytics
FOR EACH ROW
BEGIN
IF NEW.profileID = ''
THEN SET NEW.profileID = NULL;
END IF;
END;$$
DELIMITER ;

Syntax in mysql trigger

I am writing a trigger on mysql table. The code is following
DELIMITER $$
CREATE TRIGGER update_on_product_option after update on db_name.table_name
FOR each row
BEGIN
if new.isactive <> old.isactive then
SET #inc=1;
-- update statement on some table here
else if new.lastupdatedts <> old.lastupdatedts then
-- update statement on some table here
set #t = 0;
end if;
end if;
END;
$$
DELIMITER ;
As you can see there are two end if at the end and surprisingly this trigger function is not throwing any errors even though there is an extra end if; at the end. If I remove one end if, then it throws an error. unable to understand why this is happening.
Instead of ELSE IF, MySQL's syntax uses ELSEIF (without the space).
https://dev.mysql.com/doc/refman/5.7/en/if.html
DELIMITER $$
CREATE TRIGGER update_on_product_option after update on db_name.table_name
FOR each row
BEGIN
if new.isactive <> old.isactive then
SET #inc=1;
-- update statement on some table here
elseif new.lastupdatedts <> old.lastupdatedts then
-- update statement on some table here
set #t = 0;
end if;
END;
$$
DELIMITER ;
Although you might be able to make it work with the space in ELSE IF by adding an additional END IF. By using the space, you effectively initiate a second IF statement, which must be closed independently of the first outer IF statement.
This is completely normal(nested two IF stamements so both IF have to be closed):
if new.isactive <> old.isactive then
SET #inc=1;
else if new.lastupdatedts <> old.lastupdatedts then
set #t = 0;
end if;
end if;
You probably wanted:
if new.isactive <> old.isactive then
SET #inc=1;
elseif new.lastupdatedts <> old.lastupdatedts then
SET #t = 0;
end if;
The difference is ELSE IF vs ELSEIF.
Use elseif (without space ) instead of else if. The reasion is when you use else if with space its consider else is use with starting if and you create new condition with if so its required to close with end if. So in your query required two end if.
DELIMITER $$ CREATE TRIGGER update_on_product_option after update on db_name.table_name FOR each row BEGIN if new.isactive <> old.isactive then SET #inc=1; -- update statement on some table here elseif new.lastupdatedts <> old.lastupdatedts then -- update statement on some table here set #t = 0; end if; END; $$ DELIMITER ;

Stored procedure parameter to variables

This is one of those "can it be done" questions. I've got a stored procedure that could take quite a few input parameters so I was wondering if I can establish one input parameter and then set variables based off the comma separated input. Example...
drop procedure if exists sptest;
delimiter $$
create procedure sptest (v1 varchar(254))
begin
if v1=1 then set #vx1:='test1';end if;
if v1=2 then set #vx2:='test2';end if;
if v1=3 then set #vx3:='test3';end if;
if v1=4 then set #vx4:='test4';end if;
select v1;
select #vx1,#vx2,#vx3,#vx4;
end
call sptest('1,2,3,4');
If possible, any examples/guidance would be appreciated.
MySQL comes with a string function named FIND_IN_SET. I think that's your answer. Here's how it works for you:
DROP PROCEDURE IF EXISTS sptest;
DELIMITER $$
CREATE PROCEDURE sptest (v1 VARCHAR(254))
BEGIN
IF FIND_IN_SET('1', v1) THEN SET #vx1:='test1'; END IF;
IF FIND_IN_SET('2', v1) THEN SET #vx2:='test2'; END IF;
IF FIND_IN_SET('3', v1) THEN SET #vx3:='test3'; END IF;
IF FIND_IN_SET('4', v1) THEN SET #vx4:='test4'; END IF;
SELECT v1;
SELECT #vx1, #vx2, #vx3, #vx4;
END$$
CALL sptest('1,2,3,4');