MySQL workbench while loop - mysql

I am new to MySQl, I am trying to create a while loop in MySQL from the client MySQL workbench. I have tried many combinations like below but I keep getting messages like while is not valid at this position
SET #v1 = 5;
WHILE #v1 > 0 DO
SET #v1 = #v1 - 1;
END WHILE;
what can be the reason?

Related

MySQL Stored Procedure variable format not working in SELECT statement

I am having trouble getting a variable to work right in a MySQL Stored Procedure. Here is a sample of the stored procedure:
BEGIN
DECLARE x_parent varchar(100);
DECLARE term_ids_current varchar(100);
DECLARE term_ids_list INT(100);
DECLARE x_counter INT(11);
DECLARE y_counter INT(11);
DECLARE z_counter INT(11);
SET #term_ids_current = 189;
SET #term_ids_list = #term_ids_current;
SET #y_counter = 0;
SET #z_counter = 0;
parent_child: LOOP
# used for debugging #
SET #z_counter = #z_counter + 1;
# first i check to see if my criteria is met to continue the loop. #
IF EXISTS (SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (#term_ids_current)) THEN
# used for debugging #
SET #y_counter = #y_counter + 1;
BEGIN
DECLARE x_finished INT(11) DEFAULT 0;
DECLARE parent_child_cursor CURSOR FOR
SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (#term_ids_current);
# declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET x_finished = 1;
OPEN parent_child_cursor;
SET #x_counter = 0;
single_parent: LOOP
FETCH parent_child_cursor INTO x_parent;
IF x_finished = 1 THEN
LEAVE single_parent;
ELSEIF #x_counter = 0 THEN
SET #term_ids_current = x_parent;
ELSE
SET #term_ids_current = CONCAT (x_parent,",",#term_ids_current);
END IF;
SET #x_counter = #x_counter + 1;
END LOOP single_parent;
SET #term_ids_list = CONCAT (#term_ids_current,",",#term_ids_list);
CLOSE parent_child_cursor;
END;
ELSE
LEAVE parent_child;
END IF;
END LOOP parent_child;
# used for debugging #
SELECT #z_counter, #y_counter, #term_ids_current, #term_ids_list;
END;
In the single_parent loop I am populating the #term_ids_current variable with the results from my query. That variable is then used in the query for the main loop to determine if the criteria is still met. If it is then my loop happens again. I have tested each step of the procedure as an individual query and the results are accurate. The problem exists in getting the main query in the parent_child loop to run properly the second time.
When I run the SP above against my existing data set, the #term_ids_current variable contains this data set:
218,200,199,198,197,196,195,194,193,192,191,190
What I expect to happen is this data set is now passed in the query for the parent_child loop so that query would now be:
(SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (218,200,199,198,197,196,195,194,193,192,191,190))
When I run that query manually against my DB, the "IF EXISTS" statement is true meaning my parent_child loop should run again. But the loop is stopping after the IF EXISTS statement and not running again. I have verified this with the z_counter and y_counter variable. Every time I run the SP #z_counter = 2 and #y_counter = 1. So I know the IF statement is moving to the ELSE clause and not running.
To test this further I updated the SP and manually set my #term_ids_current variable at the end of the parent_child loop to see what would happen. So at the end of my altered SP I have set #term_ids_current this way:
SET #term_ids_current = (190,191,192,193,194,195,196,197,198,199,200,218);
IF #z_counter = 2 THEN
LEAVE parent_child;
END IF;
I added the second IF statement to keep the SP from running an endless loop.
Now when I execute the SP I get this error message: "MySQL said: #1241 - Operand should contain 1 column(s)." So I updated the SP again to SET the #term_ids_current variable, but this time I used double quotes instead of parentheses.
SET #term_ids_current = "190,191,192,193,194,195,196,197,198,199,200,218";
With the variable manually set the SP returns the expected result. I have tried to use both CAST and CONVERT in my SELECT statement to have the variable treated as a string. Here is an example:
SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (CONVERT(#term_ids_current,CHAR));
This does not work. If I were doing this in Python I would transform the variable for the SELECT statement with:
str(#term_ids_current)
But I cannot find a way to do this same thing in MySQL.
So my question is, how can I get my variable #term_ids_current to be treated as a string to work properly in my SELECT statement?
The query
SELECT tt.term_id
FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt
WHERE tt.parent IN (#term_ids_current)
will not work if the #term_ids_currentis a comma separated string. The reason for this is that #term_ids_current is treated as string and not as a set.
Couple of suggestions:
Instead of using a user defined variable (#var) use a temporary table for the current id's
It is better to use local variables (declare v_var int) instead of user defined variables in procedures as the scope of the user defined variable is the connection whereas the scope of the local variables is the procedure. This matters if your procedure calls other procedures that use same variables.
Try the suggestion given by #slaakso or use find_in_set
so you need to change the in clause into something similar to your codes
WHERE find_in_set(tt.parent,#term_ids_current)

Using an if statement outside a stored procedure

I am trying to execute this code
set #id = 0;
set #the_number = 0;
set #the_message = 0;
set #selected_message = 0;
SELECT id, dest_msisdn, text_message INTO #id, #the_number, #the_message FROM incoming_sms where service_id = 6015592000101762 AND job_status = 0 limit 1;
if(#the_message LIKE '%Bank%')then
select 'h';
end if;
but i keep getting an error on
if(#the_message LIKE '%Bank%')then
select 'h'' at line 1
Why is my if producing an error?.
You need to put your code inside of a strored procedure or function to use the IF statement https://stackoverflow.com/a/12954385/5308054. Here you can see a feature request to fix it https://bugs.mysql.com/bug.php?id=48777
It is possible to rewrite query without IF statements but I think this question is too to be answered in such way.

Updating a MYSQL table with multiple if statements

Having some trouble getting this MYSQL code to work. I was attempting to add an onUpdate trigger via PHPMYAdmin, that takes the row, then takes the modified entry and checks to see if it is greater than some values below.
What I was trying to do was have the code check one if statement,execute the code inside the if, and then go to the next if statement after that.I looked around but couldn't figure out where I went wrong. Help is appreciated!
The code:
IF NEW.someVal> 10 THEN
UPDATE someTable
SET someTable.colA = someTable.colA +1;
END IF;
IF NEW.someVal > 50 THEN
UPDATE someTable
SET someTable.colB = someTable.colB +1;
END IF;
IF NEW.someVal > 100 THEN
UPDATE someTable
SET someTable.colC = someTable.colC +1;
END IF;
The 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 'IF NEW.someVal > 10 THEN
UPDATE someTable.co'... at line 6
If I were to take any of these if statements, and only use on of them in the trigger I'm trying to create, the trigger works fine.
You could implement the same functionality without using the IF condition, as follows:
UPDATE someTable
SET someTable.colA = someTable.colA +1
WHERE someTable.colA +1 > 10;
UPDATE someTable
SET someTable.colB = someTable.colB +1
WHERE someTable.colB +1 > 50;
UPDATE someTable
SET someTable.colC = someTable.colC +1
WHERE someTable.colC +1 > 100;

How to set up a WHILE loop with IF statement in MySQL?

I would like to create a stored routine for MySQL that figures out the number of business or working days for a month (Working Days are Monday thru Friday).
It's a syntax error however I don't know what the syntax error is. All it tells me is:
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 'WHILE(#daycount < #totaldays) DO IF (WEEKDAY(#checkweekday) < 6)
THEN ' at line 2
My Syntax Error is in the following:
WHILE(#daycount < #totaldays) DO
IF (WEEKDAY(#checkweekday) < 6) THEN
My Code:
SELECT MONTH(CURDATE()) INTO #curmonth;
SELECT MONTHNAME(CURDATE()) INTO #curmonthname;
SELECT DAY(LAST_DAY(CURDATE())) INTO #totaldays;
SELECT FIRST_DAY(CURDATE()) INTO #checkweekday;
SELECT DAY(#checkweekday) INTO #checkday;
SET #daycount = 0;
SET #workdays = 0;
BEGIN
WHILE(#daycount < #totaldays) DO
IF (WEEKDAY(#checkweekday) < 6) THEN
SET #workdays = #workdays+1;
END IF;
SET #daycount = #daycount+1;
SELECT ADDDATE('#checkweekday', INTERVAL 1 DAY) INTO #checkweekday;
END WHILE;
END;
SELECT #workdays;
Is someone able to assist?
UPDATE
I receive the same error with the following bit of code so it probably has something to do with this:
SET #workdays = 0;
IF (WEEKDAY('2013-06-13') < 6) THEN
SET #workdays = #workdays+1;
END IF;
SELECT #workdays;
I have discovered that you cannot have conditionals outside of the stored procedure in mysql. This is why the syntax error. As soon as I put the code that I needed between
BEGIN
SELECT MONTH(CURDATE()) INTO #curmonth;
SELECT MONTHNAME(CURDATE()) INTO #curmonthname;
SELECT DAY(LAST_DAY(CURDATE())) INTO #totaldays;
SELECT FIRST_DAY(CURDATE()) INTO #checkweekday;
SELECT DAY(#checkweekday) INTO #checkday;
SET #daycount = 0;
SET #workdays = 0;
WHILE(#daycount < #totaldays) DO
IF (WEEKDAY(#checkweekday) < 5) THEN
SET #workdays = #workdays+1;
END IF;
SET #daycount = #daycount+1;
SELECT ADDDATE(#checkweekday, INTERVAL 1 DAY) INTO #checkweekday;
END WHILE;
END
Just for others:
If you are not sure how to create a routine in phpmyadmin you can put this in the SQL query
delimiter ;;
drop procedure if exists test2;;
create procedure test2()
begin
select ‘Hello World’;
end
;;
Run the query. This will create a stored procedure or stored routine named test2. Now go to the routines tab and edit the stored procedure to be what you want. I also suggest reading http://net.tutsplus.com/tutorials/an-introduction-to-stored-procedures/ if you are beginning with stored procedures.
The first_day function you need is:
How to get first day of every corresponding month in mysql?
Showing the Procedure is working
Simply add the following line below END WHILE and above END
SELECT #curmonth,#curmonthname,#totaldays,#daycount,#workdays,#checkweekday,#checkday;
Then use the following code in the SQL Query Window.
call test2 /* or whatever you changed the name of the stored procedure to */
NOTE: If you use this please keep in mind that this code does not take in to account nationally observed holidays (or any holidays for that matter).

Iterate 50 times over an SQL command

I want to make propotion codes for my product.
I have created an appropriate SQL statement which basically uses the current timestamp and runs SHA1 on it.
I tried a while ago to create an iterative loop over my INSERT command but failed
anyone know how?
Do 50 times
INSERT INTO ......
end
Also, I cannot have two of the same promotion code so the timestamp needs to be different for each iteration (If it is at all possible that the timestamp might be the same between iterations).
write the code in python or some other scripting language.
Use a GUID for the promotion code rather than a hash of the timestamp.
http://dev.mysql.com/doc/refman/5.0/en/flow-control-constructs.html
Your approach with using the PROCEDURE is the best I guess. I would first set another delimiter, because you are using the ';' already:
delimiter //
After that define your procedure. The INSERT INTO ...... is your INSERT code, what you wrote in your question.
CREATE PROCEDURE createPromotions(p1 INT)
BEGIN
SET #x = 0;
REPEAT
SET #x = #x + 1;
INSERT INTO ......
UNTIL #x > p1
END REPEAT;
END
//
After entering the '//' the procedure is ready to CALL. And if you want to execute it 50 times, just call it 50 times:
CALL createPromotions(50)
This is pretty dirty, but if you have any table on your system which you know has more than 50 rows, you can do the following:
create table promotion_code ( pc varchar(100) );
set #c = 1;
insert into promotion_code
select sha1( now() + (#c := #c + 1 ) )
from mysql.help_relation limit 50;
CREATE PROCEDURE createPromotions(p1 INT)
BEGIN
SET #x = 0;
REPEAT SET #x = #x + 1; UNTIL #x > p1 END REPEAT;
END
Some sort of proceedure like this would be nice but I don't know how to get it into the format I need. which is to repeat an SQL statement 50 times