Declare inside if condition showing syntax error - MYSQL Triggers - mysql

I try to update some columns using trigger before insert
DROP TRIGGER IF EXISTS update_p_posts_places;
DELIMITER $$
CREATE TRIGGER update_p_posts_places BEFORE
INSERT
ON
`p_posts` FOR EACH ROW
BEGIN
DECLARE
p_post_group_id_ int;
SELECT
`p_post_subgroup`.`p_post_group_id`
INTO
p_post_group_id_
FROM
`p_post_subgroup`
WHERE
`p_post_subgroup`.`p_post_subgroup_id` = NEW.p_post_subgroup_id;
IF(p_post_group_id_ = 5) THEN
BEGIN
DECLARE
place1_id_ int;
place2_id_ int;
place3_id_ int;
place4_id_ int;
place5_id_ int;
SELECT
`Places`.`place1_id`,
`Places`.`place2_id`,
`Places`.`place3_id`,
`Places`.`place4_id`,
`Places`.`place5_id`
INTO
place1_id_, place2_id_, place3_id_, place4_id_, place5_id_
FROM
`Places`
WHERE
`Places`.`place5_id` = NEW.p_post_place_id LIMIT 1;
SET NEW.place5_id = place5_id_;
SET NEW.place1_id = place1_id_;
SET NEW.place2_id = place2_id_;
SET NEW.place3_id = place3_id_;
SET NEW.place4_id = place4_id_;
END $$
ELSE
SET NEW.place5_id = NULL;
END IF;
END $$
DELIMITER ;
It's showing some syntax errors.
#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
place1_id_ int;
place2_id_ int;
' at line 20

Here is a working trigger. I tested creating it on MySQL 5.7.
CREATE TRIGGER update_p_posts_places BEFORE INSERT ON `p_posts`
FOR EACH ROW
BEGIN
-- all declarations must be before any other statements
DECLARE p_post_group_id_, place1_id_, place2_id_, place3_id_,
place4_id_, place5_id_ int;
SELECT
`p_post_subgroup`.`p_post_group_id`
INTO
p_post_group_id_
FROM
`p_post_subgroup`
WHERE
`p_post_subgroup`.`p_post_subgroup_id` = NEW.p_post_subgroup_id;
IF(p_post_group_id_ = 5) THEN
SELECT
`Places`.`place1_id`,
`Places`.`place2_id`,
`Places`.`place3_id`,
`Places`.`place4_id`,
`Places`.`place5_id`
INTO
place1_id_, place2_id_, place3_id_, place4_id_, place5_id_
FROM
`Places`
WHERE
`Places`.`place5_id` = NEW.p_post_place_id LIMIT 1;
SET NEW.place5_id = place5_id_;
SET NEW.place1_id = place1_id_;
SET NEW.place2_id = place2_id_;
SET NEW.place3_id = place3_id_;
SET NEW.place4_id = place4_id_;
ELSE
SET NEW.place5_id = NULL;
END IF;
END $$
You can use one DECLARE for multiple local variables, but you must do like var1, var2, var3, ... int. In other words, name the type only once at the end. See documentation: https://dev.mysql.com/doc/refman/8.0/en/declare-local-variable.html
No need for the BEGIN..END inside the IF and definitely do not use $$ until after the last END because that will terminate the parser's interpretation of your whole CREATE TRIGGER statement before it's complete.

Related

Create mysql trigger before insert (Syntax error)

Hi i am creating some trigger for update the value in insert query before insert the row like this
CREATE TRIGGER `Insert members in Posts` BEFORE INSERT ON
`posts` FOR EACH ROW
BEGIN
DECLARE name_ varchar(100);
DECLARE contact_ varchar(16);
DECLARE status_ int;
DECLARE deleted_ int;
SELECT
`members`.`name`,
`members`.`contact`,
`members`.`status`,
`members`.`deleted`
INTO name_, contact_, status_, deleted_
FROM
`members`
WHERE
`members`.`member_id` = NEW.member_id;
SET NEW.member_name = name_;
SET NEW.member_contact = contact_;
SET NEW.member_status = status_;
SET NEW.member_deleted = deleted;
END
But i received the error like
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 4
I am little confused what's the error in line no 4. Please explain someone. Thanks.
Depending on the client/ide used you may need to set delimiter for example
drop trigger if exists t;
delimiter $$
CREATE TRIGGER t BEFORE INSERT ON
`posts` FOR EACH ROW
BEGIN
DECLARE name_ varchar(100);
DECLARE contact_ varchar(16);
DECLARE status_ int;
DECLARE deleted_ int;
SELECT
`members`.`name`,
`members`.`contact`,
`members`.`status`,
`members`.`deleted`
INTO name_, contact_, status_, deleted_
FROM
`members`
WHERE
`members`.`member_id` = NEW.member_id;
SET NEW.member_name = name_;
SET NEW.member_contact = contact_;
SET NEW.member_status = status_;
SET NEW.member_deleted = deleted;
END $$
delimiter ;
please review https://dev.mysql.com/doc/refman/8.0/en/stored-routines.html

Mysql - Print all the values in between #loop_start_date to #loop_end_date

I am trying to:
1. Print all the values in between #loop_start_date to #loop_end_date
2. loop_start_date should be increased by 1 here till loop_start_date=loop_end_date
I tried below but Mysql says
#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 'BEGIN Declare #user_id int' at line 3
Here is the procedure code
CREATE PROCEDURE generatePayscale
BEGIN
Declare #user_id int;
Declare #office_id int;
Declare #loop_start_date Date;
Declare #loop_end_date Date;
SET #user_id = 1287;
SET #office_id = 8;
SET #loop_start_date = '2018-06-02';
SET #loop_end_date = '2018-06-06';
WHILE(#loop_start_date < #loop_end_date) do
SELECT old_paysetupid
FROM personneltransfer personnelid=#user_id
AND pt.transferdate>#loop_start_date
END WHILE;
END
This may point you in the correct direction, a few things i would change. Added BEGIN. Then added declare for each of the vars. Then you need a where after the from
SET #user_id = 1287;
SET #office_id = 8;
SET #loop_start_date = '2018-06-02';
SET #loop_end_date = '2018-06-06';
WHILE(#loop_start_date < #loop_end_date) do
BEGIN
SELECT old_paysetupid
FROM personneltransfer where personnelid=#user_id
and pt.transferdate>#loop_start_date
END WHILE;

SQL: Create table with term names (String containing years)

I would like to create a table (two columns, first is auto incremental) which contains the term names, e.g. "SS 2000" and "WS 2000/2001" (for summer and winter term).
I tried the following:
CREATE PROCEDURE create_terms()
BEGIN
Declare #YearEnd integer;
SET #YearEnd = 2014;
Declare #YearFrom integer = #YearEnd - 100;
Declare #Term varchar = '';
while #YearFrom < #YearEnd Begin
#Term = concat('SS ', #YearFrom);
Insert into terms (term) VALUES #Term;
Set #YearFrom = #YearFrom + 1;
End
END
but I already get an error in line 3: SQL query:
CREATE PROCEDURE create_terms()
BEGIN
Declare #YearEnd integer;
MySQL said: Documentation #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 '#YearEnd integer' at line 3
After reading the comments from Abishek and Stuart, I tried the following:
DELIMITER $$
DROP PROCEDURE IF EXISTS create_terms$$
CREATE PROCEDURE create_terms()
BEGIN
DECLARE YearEnd INT;
Declare YearFrom INT;
Declare Term varchar(10);
SET YearEnd = 2014;
SET YearFrom = YearEnd - 100;
SET Term= '';
WHILE (YearFrom < YearEnd) DO
SET Term = concat('SS ', YearFrom);
Insert into terms (term) VALUES (Term);
Set YearFrom = YearFrom + 1;
END WHILE;
END;
DELIMITER ;
This results in just the DROP PROCEDURE command being successfully processed. Even when removing this line and changing the first lines to:
DELIMITER $$
CREATE PROCEDURE create_terms()$$
BEGIN
it doesn't work, the SQl console just writes "ERROR" and that's it.... :(
There are quite a bunch of errors here
You should use procedure variables
The Syntax for insert is INSERT INTO Table(columns) VALUES(values);
You probably also want to insert the term, not the year end
Your syntax for while is wrong
CREATE PROCEDURE create_terms()
BEGIN
DECLARE YearEnd INT;
Declare YearFrom INT;
Declare Term varchar(10);
SET YearEnd = 2014;
SET YearFrom = YearEnd - 100;
SET Term= '';
WHILE (YearFrom < YearEnd) DO
SET Term = concat('SS ', YearFrom);
Insert into terms (term) VALUES (Term);
Set YearFrom = YearFrom + 1;
END WHILE;
END
Fiddle here
All variable staring # are user variables and need not to be declared, procedures has their local variables not prefix with #, try like this:
DELIMITER $$
DROP PROCEDURE IF EXISTS create_terms$$
CREATE PROCEDURE create_terms()
BEGIN
Declare YearEnd integer;
SET YearEnd = 2014;
Declare YearFrom integer = YearEnd - 100;
Declare Term varchar = '';
while YearFrom < YearEnd Begin
Term = concat('SS ', YearFrom);
Insert into terms (term) VALUES YearFrom;
Set YearFrom = YearFrom + 1;
End;
END;
DELIMITER ;
Here is help

MySQL: Solve my MySQL Cursor Error:1064

DROP TRIGGER IF EXISTS `ACTUALIZAR_LOTE_DETALLE`;
DELIMITER //
CREATE TRIGGER `ACTUALIZAR_LOTE_DETALLE` AFTER INSERT ON `detalle_envio`
FOR EACH ROW BEGIN
DECLARE ID_INVENTARIO_IN INT;
DECLARE ID_LOTE_DETALLE_MIN INT;
DECLARE CANTIDAD_A_COMPARAR INT;
DECLARE CANTIDAD_A_RESTAR INT;
SET CANTIDAD_A_RESTAR = new.cantidad_enviado;
SET ID_INVENTARIO_IN = (Select id_inventario from detalle_requisicion WHERE id_detalle_requisicion = new.id_detalle_requisicion);
DECLARE cur_id CURSOR FOR SELECT id_lote_detalle from lote_detalle WHERE id_inventario = ID_INVENTARIO_IN AND cantidad > 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = 1;
OPEN cur_id;
read_loop: LOOP
FETCH cur_id INTO LOTE_DETALLE_IDS;
SET CANTIDAD_A_COMPARAR = select cantidad from lote_detalle where id_lote_detalle = LOTE_DETALLE_IDS;
IF CANTIDAD_A_RESTAR > CANTIDAD_A_COMPARAR THEN
UPDATE `lote_detalle` SET cantidad=cantidad-CANTIDAD_A_COMPARAR WHERE id_lote_detalle = LOTE_DETALLE_IDS;
SET CANTIDAD_A_RESTAR = CANTIDAD_A_RESTAR - CANTIDAD_A_COMPARAR;
ELSE
UPDATE `lote_detalle` SET cantidad=cantidad-CANTIDAD_A_RESTAR WHERE id_lote_detalle = LOTE_DETALLE_IDS;
LEAVE read_loop;
END IF;
IF DONE = 1 THEN
LEAVE read_loop;
END IF;
END LOOP read_loop;
CLOSE cur_id;
END
//
DELIMITER ;
Is anything in the cursor?
the query or something?
Is anything in the Syntax?
Cause i have based this Trigger from the syntax of the MySQL Forums
This is 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 'DECLARE cur_id CURSOR FOR SELECT id_lote_detalle from lote_detalle WHERE id_inve' at line 9
There are at least following issues with your code:
All declarations should come before any statements (SET in your case). That's what is causing your immediate error.
You didn't declare DONE variable
You didn't declare LOTE_DETALLE_IDS variable, but you declared ID_LOTE_DETALLE_MIN which you didn't use. Perhaps you should rename ID_LOTE_DETALLE_MIN to LOTE_DETALLE_IDS then.
Since declarations go first you have to re-write your cursor definition (e.g. with subquery) because ID_INVENTARIO_IN variable isn't initialized yet
Your whole declaration section can be re-written in a following manner
-- declaration of variables of the same type can be combined
DECLARE ID_INVENTARIO_IN,
LOTE_DETALLE_IDS,
CANTIDAD_A_COMPARARINT,
CANTIDAD_A_RESTAR,
DONE INT;
DECLARE cur_id CURSOR FOR ...
DECLARE CONTINUE HANDLER ...
-- initialize variables
SET ...
Now, I believe your trigger most likely can be re-written with just update statement(s). You can get help with it if you explain in plain words what you're trying to achieve and provide exact table schemas and sample data.

Error declaring integer variable inside MySQL stored function

I'm getting an error when trying to declare a new stored function in MySQL (Server version: 5.5.13)
Basically, I have a large table which classifies strings depending on how they start. My function takes a string (from user input) and then tells you the classification of that string by searching the database for the classification. It's a bit like a LIKE query, except in reverse as it's the user input that contains the full string and the database contains the string being searched for. Hope that makes sense!
The concept and logic behind it work fine as I've written/developed this in PHP and it works beautifully, however when trying to translate this into a stored function I'm getting an error from MySQL. The code of the function is:
delimiter $
DROP FUNCTION IF EXISTS get_string_class$
CREATE FUNCTION get_string_class(mystring VARCHAR(15))
RETURNS VARCHAR(15)
READS SQL DATA
BEGIN
DECLARE i INT;
SET i = 2;
DECLARE mystringlength INT;
SET mystringlength = LENGTH(mystring);
DECLARE segment VARCHAR(15);
DECLARE String_Class VARCHAR(15);
SET String_Class = NULL;
WHILE i <= mystringlength DO
SET segment = LEFT(mystring, i);
SET String_Class = (SELECT String_Class FROM string_class_list WHERE String_Begins = segment);
IF SELECT FOUND_ROWS() = 1 THEN
RETURN String_Class
END IF;
i = i + 1;
END WHILE;
RETURN String_Class;
END$
delimiter ;
I'm getting this 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
'DECLARE mystringlength INT; SET mystringlength = LENGTH(mystring);
DECLARE segm' at line 10
I've done lots of playing around to trying and work out where I'm going wrong. I've even stripped out the loop altogether to test it, but still get the same error. Does anyone know what I've done wrong where declaring that INT variable? It's probably something incredibly basic...!
Thanks very much in advance.
There were some syntax errors -
One of them is - all declarations must be at the begining of the BEGIN...END clause.
DELIMITER $
DROP FUNCTION IF EXISTS get_string_class$
CREATE FUNCTION get_string_class(mystring VARCHAR(15))
RETURNS VARCHAR(15)
READS SQL DATA
BEGIN
DECLARE i INT;
DECLARE segment VARCHAR(15);
DECLARE String_Class VARCHAR(15);
DECLARE mystringlength INT;
SET i = 2;
SET mystringlength = LENGTH(mystring);
SET String_Class = NULL;
WHILE i <= mystringlength DO
SET segment = LEFT(mystring, i);
SET String_Class = (SELECT String_Class FROM string_class_list WHERE String_Begins = segment);
IF (SELECT FOUND_ROWS()) = 1 THEN
RETURN String_Class;
END IF;
SET i = i + 1;
END WHILE;
RETURN String_Class;
END$
DELIMITER ;
DECLARE part inside stored procedure must be at top and SET and other statemnts starts after that.