i tried my best to have a better title for the question but thats all i could make up. Well i will try to explain it by giving an example. Assume i have: Set x = 100200300;
Set y = 10; B
Now i want to add y into all first 3 numbers which is “100” then add it into “200” and so on. I was wondering if i can do it with “select left” function inside a loop? Not sure how to apply it tho therefore i am seeking for help here. Help me please. Bless
DELIMITER $$
CREATE PROCEDURE proc(
)
BEGIN
DECLARE counter INT DEFAULT 1;
set #x = '100200300400';
set #y = 10;
WHILE counter <= #x DO
select concat(substring(#x,counter,3) + #y,substring(#x,(counter +3),3) + #y) x;
END WHILE;
END$$
DELIMITER ;
Perhaps
SET #X = 100200300;
SET #Y = 10;
select concat(substring(#x,1,3) + #y,substring(#x,4,3) + #y,substring(#x,7,3) + #y) x;
+-----------+
| x |
+-----------+
| 110210310 |
+-----------+
1 row in set (0.001 sec)
If x is of unknown length
DROP PROCEDURE IF EXISTS P;
DELIMITER $$
CREATE PROCEDURE p(
)
BEGIN
DECLARE counter INT DEFAULT 1;
set #x = '100200300400';
set #y = 10;
SET #OUT = '';
L:WHILE counter <= #x / 3 DO
#SELECT COUNTER;
IF #x is null or COUNTER > 10 THEN LEAVE L; END IF;
SET #OUT = CONCAT(#OUT,substring(#x,counter,3) + #y);
SET #X = REPLACE(#X,#out,'');
#select concat(substring(#x,counter,3) + #y,substring(#x,(counter +3),3) + #y) x;
SET COUNTER = COUNTER + 3;
END WHILE;
select #out;
END $$
DELIMITER ;
CALL P();
DELIMITER ;
Related
I'm looking to do some validation of data replication between some different database systems, with different character sets (potentially) and a third party software that migrates the data. To help test an aspect of this, I'm looking to do something like the following.
ASCII(foo) returns the value for the first character in the string. Is there a way to get the ascii values for all characters in a string in one go, in one select statement? Something like concating the values together, separated by a space. E.g. If the string was hello then the output would be 104 101 108 108 111
Reference:
select ascii('h'); -- 104
select ascii('e'); -- 101
select ascii('l'); -- 108
select ascii('o'); -- 111
Just had the same problem, so here is a procedure that does the work:
DELIMITER $$
CREATE PROCEDURE string_to_ascii(IN inputStr VARCHAR(255))
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE idx INT DEFAULT 0;
DECLARE current_char VARCHAR(1);
DECLARE current_char_ascii VARCHAR(10);
DECLARE outputStr TEXT;
IF inputStr IS NULL THEN
SET inputStr = '';
END IF;
SET strLen = CHAR_LENGTH(inputStr);
SET idx = 1;
WHILE idx <= strLen DO
SET current_char = SUBSTR(inputStr, idx, 1);
SET current_char_ascii = ASCII(current_char);
IF idx = 1 THEN
SET outputStr = current_char_ascii;
ELSE
SET outputStr = CONCAT(outputStr, ",", current_char_ascii);
END IF;
SET idx = idx+1;
END WHILE;
SELECT outputStr;
END
$$
DELIMITER ;
Usage:
> CALL string_to_ascii('hello');
+---------------------+
| outputStr |
+---------------------+
| 104,101,108,108,111 |
+---------------------+
If you prefer to use it as a function:
DELIMITER //
CREATE FUNCTION string_to_ascii ( inputStr TEXT )
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE idx INT DEFAULT 0;
DECLARE current_char VARCHAR(1);
DECLARE current_char_ascii VARCHAR(10);
DECLARE outputStr TEXT;
IF inputStr IS NULL THEN
SET inputStr = '';
END IF;
SET strLen = CHAR_LENGTH(inputStr);
SET idx = 1;
WHILE idx <= strLen DO
SET current_char = SUBSTR(inputStr, idx, 1);
SET current_char_ascii = ASCII(current_char);
IF idx = 1 THEN
SET outputStr = current_char_ascii;
ELSE
SET outputStr = CONCAT(outputStr, ",", current_char_ascii);
END IF;
SET idx = idx+1;
END WHILE;
RETURN outputStr;
END; //
DELIMITER ;
And then the usage will be:
> SELECT string_to_ascii('hello');
+--------------------------+
| string_to_ascii('hello') |
+--------------------------+
| 104,101,108,108,111 |
+--------------------------+
I have this code for insert rows to table. I have three while nesthed themself, but this code give me
error #1064 - bad syntax close
BEGIN
WHILE p <= 5
BEGIN
WHILE ra <= 40
' on line 7.
What is wrong with this code?
DELIMITER $$
CREATE PROCEDURE proc()
BEGIN
DECLARE r int DEFAULT 1;
DECLARE p int DEFAULT 1;
DECLARE ra int DEFAULT 1;
WHILE r <= 8 DO
WHILE p <= 5 DO
WHILE ra <= 40 DO
INSERT INTO tabulka (REGAL,POLICE,RADA) VALUES(r,p,ra);
SET ra = ra + 1;
END WHILE;
SET p = p + 1;
END WHILE;
SET r = r + 1;
END WHILE;
END$$
DELIMITER ;
CALL proc();
EDIT: Now it generates only one loop:
MySQL uses WHILE DO/END WHILE for it syntax. So the stored procedure should look like this:
CREATE PROCEDURE proc()
BEGIN
DECLARE r int DEFAULT 1;
DECLARE p int DEFAULT 1;
DECLARE ra int DEFAULT 1;
WHILE r <= 8 DO
WHILE p <= 5 DO
WHILE ra <= 40 DO
INSERT INTO tabulka (REGAL,POLICE,RADA) VALUES(r,p,ra);
SET ra = ra + 1;
END WHILE;
SET p = p + 1;
END WHILE;
SET r = r + 1;
END WHILE;
END;
Here is a little rextester.
Okay, my mistake. I forgot to reset variables to 1 after inside loops was done. Thanks for help.
i'm having hard time with my homework , because im beginner using mysql procedure.
to search total numbers odd and even between 20-50 with looping.
i want to make output like this using mysql procedure to call:
total_odd_numbers :15
total_even_numbers:16
i tried for sum up for even numbers like this :
`DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `genap`()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
declare total int;
SET x = 20;
SET str = '';
set total = 0;
loop_label: LOOP
IF x = 50 THEN
LEAVE loop_label;
END IF;
SET x =x+1;
IF (x mod 2) THEN
ITERATE loop_label;
ELSE
SET str = CONCAT(str,x,',');
SET total= total+x;
END IF;
END LOOP;
SELECT sum(total);
END`
Try this procedure:
DROP PROCEDURE IF EXISTS ShowOddEvesBetween;
DELIMITER ;;
CREATE PROCEDURE ShowOddEvesBetween(IN fromNum INT, IN toNum INT)
BEGIN
DECLARE odds INT DEFAULT 0;
DECLARE evens INT DEFAULT 0;
DECLARE x INT;
SET x = fromNum;
WHILE x <= toNum DO
IF x % 2 THEN
SET odds = odds + 1;
ELSE
SET evens = evens + 1;
END IF;
SET x = x + 1;
END WHILE;
SELECT CONCAT("total_odd_numbers: ", odds, ", total_even_numbers: ", evens) AS "Odds & Evens";
END;
;;
Then call it
CALL ShowOddEvesBetween(20, 50);
Will output what you want
MariaDB [test]> CALL ShowOddEvesBetween(20, 50);
+-----------------------------------------------+
| Odds & Evens |
+-----------------------------------------------+
| total_odd_numbers: 15, total_even_numbers: 16 |
+-----------------------------------------------+
1 row in set (0.00 sec)
I Have a table somewhat like this:
rnumber
number = int, cod = int
SELECT * FROM number WHERE number = 21377 and cod = 55;
returns the correct value;
So i have a proc call to insert:
CREATE DEFINER=`root`#`%` PROCEDURE `create`(IN Numb INT, IN Cod INT, IN qt INT)
BEGIN
SET #Cont = 0;
SET #Init = Numb;
WHILE #Cont < qt DO
SET #Exist = (SELECT count(number) FROM rnumber WHERE number = #Init AND cod = Cod LIMIT 1);
IF #Exist = 0 THEN
INSERT INTO (...)
END IF;
SET #Cont = #Cont + 1;
SET #IniT = #Init + 1;
END WHILE;
END$$
CALL create (21377, 54, 1);
Always give me variable #Exist as 1, so no go on the if, even tho the combination of number and cod does not exists.
Can anyone point me what am i doing wrong?
Thank you.
Try using select into instead of set xx = (select...).
Also having cod = Cod will always return true...
You also need to declare your variables...
Try this one:
CREATE DEFINER=`root`#`%` PROCEDURE `create`(IN p_Numb INT, IN p_Cod INT, IN p_qt INT)
BEGIN
declare v_Exist integer;
declare v_Init integer;
declare v_Exist integer;
SET v_Cont = 0;
SET v_Exist = 0;
SET v_Init = p_Numb;
WHILE v_Cont < p_qt DO
SELECT count(number) into v_Exist FROM rnumber WHERE number = v_Init AND cod = p_Cod LIMIT 1;
IF v_Exist = 0 THEN
INSERT INTO (...)
END IF;
SET v_Cont = v_Cont +1;
SET v_IniT = v_Init + 1;
END WHILE;
END$$
In MySQL, I have this stored procedure with a LOOP:
DELIMITER $$
CREATE PROCEDURE ABC()
BEGIN
DECLARE a INT Default 0 ;
simple_loop: LOOP
SET a=a+1;
select a;
IF a=5 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$
It always prints 1. What is the correct syntax for a MySQL Loop?
drop table if exists foo;
create table foo
(
id int unsigned not null auto_increment primary key,
val smallint unsigned not null default 0
)
engine=innodb;
drop procedure if exists load_foo_test_data;
delimiter #
create procedure load_foo_test_data()
begin
declare v_max int unsigned default 1000;
declare v_counter int unsigned default 0;
truncate table foo;
start transaction;
while v_counter < v_max do
insert into foo (val) values ( floor(0 + (rand() * 65535)) );
set v_counter=v_counter+1;
end while;
commit;
end #
delimiter ;
call load_foo_test_data();
select * from foo order by id;
While loop syntax example in MySQL:
delimiter //
CREATE procedure yourdatabase.while_example()
wholeblock:BEGIN
declare str VARCHAR(255) default '';
declare x INT default 0;
SET x = 1;
WHILE x <= 5 DO
SET str = CONCAT(str,x,',');
SET x = x + 1;
END WHILE;
select str;
END//
Which prints:
mysql> call while_example();
+------------+
| str |
+------------+
| 1,2,3,4,5, |
+------------+
REPEAT loop syntax example in MySQL:
delimiter //
CREATE procedure yourdb.repeat_loop_example()
wholeblock:BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 5;
SET str = '';
REPEAT
SET str = CONCAT(str,x,',');
SET x = x - 1;
UNTIL x <= 0
END REPEAT;
SELECT str;
END//
Which prints:
mysql> call repeat_loop_example();
+------------+
| str |
+------------+
| 5,4,3,2,1, |
+------------+
FOR loop syntax example in MySQL:
delimiter //
CREATE procedure yourdatabase.for_loop_example()
wholeblock:BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = -5;
SET str = '';
loop_label: LOOP
IF x > 0 THEN
LEAVE loop_label;
END IF;
SET str = CONCAT(str,x,',');
SET x = x + 1;
ITERATE loop_label;
END LOOP;
SELECT str;
END//
Which prints:
mysql> call for_loop_example();
+-------------------+
| str |
+-------------------+
| -5,-4,-3,-2,-1,0, |
+-------------------+
1 row in set (0.00 sec)
Do the tutorial: http://www.mysqltutorial.org/stored-procedures-loop.aspx
If I catch you pushing this kind of MySQL for-loop constructs into production, I'm going to shoot you with the foam missile launcher. You can use a pipe wrench to bang in a nail, but doing so makes you look silly.
Assume you have one table with name 'table1'. It contain one column 'col1' with varchar type. Query to crate table is give below
CREATE TABLE `table1` (
`col1` VARCHAR(50) NULL DEFAULT NULL
)
Now if you want to insert number from 1 to 50 in that table then use following stored procedure
DELIMITER $$
CREATE PROCEDURE ABC()
BEGIN
DECLARE a INT Default 1 ;
simple_loop: LOOP
insert into table1 values(a);
SET a=a+1;
IF a=51 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$
To call that stored procedure use
CALL `ABC`()
You can exchange this local variable for a global, it would be easier.
DROP PROCEDURE IF EXISTS ABC;
DELIMITER $$
CREATE PROCEDURE ABC()
BEGIN
SET #a = 0;
simple_loop: LOOP
SET #a=#a+1;
select #a;
IF #a=5 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$