MySQL build a variable name? - mysql

I am trying to build a variable name dynamically within a user defined function but it seems it does not work. Is there a way to do this or by using an array variable?
I have a string of 7 characters which represents the days of the week (1234567, or 1_3_5_7, etc.). I would like evaluate how often during a week a day is selected (from 0 to 7). I thought, it would be easiest to use a loop to go through all the 7 positions but I get an error message saying
[Err] 1193 - Unknown system variable 'CONCAT'
Any hints on how I can achieve that? This is my code:
DELIMITER $$
DROP FUNCTION IF EXISTS fn_freq$$
CREATE FUNCTION fn_freq(days INT) RETURNS INT
BEGIN
DECLARE D1 VARCHAR(1);
DECLARE D2 VARCHAR(1);
DECLARE D3 VARCHAR(1);
DECLARE D4 VARCHAR(1);
DECLARE D5 VARCHAR(1);
DECLARE D6 VARCHAR(1);
DECLARE D7 VARCHAR(1);
DECLARE x INT;
DECLARE fn_freq INT;
SET x =1;
SET fn_freq = 0;
WHILE x < 8 DO
SET CONCAT('D',x) = MID(days, x, 1);
IF CONCAT('D',x) = '_' THEN
ELSE
SET fn_freq = fn_freq + 1;
SET x = x + 1;
END IF;
SET x = x + 1;
END WHILE;
RETURN fn_freq;
END$$
DELIMITER ;

You cant SET CONCAT as in SET CONCAT('D',x) = MID(days, x, 1) what instead i think will be better to declare & set the concat value to that variable and use that variable for the IF condition. Also I think you missed out what have to be done in the case IF Condition is true.

Thanks for your reply. I got it to work like this, but I am still curious, how I could dynamically create a variable in some other cases.
For this function, I realized I don't even need the variable, as I can evaluate it straight in the if clause.
DELIMITER $$
DROP FUNCTION IF EXISTS fn_freq$$
CREATE FUNCTION fn_freq(days VarChar(7)) RETURNS INT
BEGIN
DECLARE x INT;
DECLARE fn_freq INT;
SET x =1, fn_freq = 0;
WHILE x < 8 DO
IF MID(days, x, 1) <> '_' THEN
SET fn_freq = fn_freq + 1;
END IF;
SET x = x + 1;
END WHILE;
RETURN fn_freq;
END$$
DELIMITER ;

Related

¿Why this returns 0?

Thats return me 0. Why? i need som like this 1/8 + 1/7 + 1/6....1/m
Srry for my code, im learning sql.
delimiter //
drop function if exists divide;
create function divide(m int) returns decimal(30,3) deterministic
begin
declare m int;
declare n decimal(30,3) default 0;
declare x decimal(30,3) default 0;
while m>=1 do
set n=n+x;
select 1/m into x;
set m=m-1;
end while;
return n;
end;//
delimiter ;
select divide(8);
Thanks you all, the solution was that i declared two times m.

Insert n number of rows into table when input string contains n number of fields in mysql

I do have a requirement like when two inputs are passed as input to stored proc, inserting into another table need to happen and the number of rows will depend on number of fields passed in input.
I have tried to create a stored proc but its only inserting taking field length as 1
BEGIN
Declare valu varchar(200);
Declare valu2 varchar(200);
Declare fwo varchar(200);
Declare fwo2 varchar(200);
declare len int;
Declare sl int;
Declare valu3 varchar(255);
Declare jval varchar(255);
set #fwo = (select replace(pinput1,',', ''));
set #fwo2 = (select replace(pinput2,',', ''));
-- select #fwo;
set #len = (select length(#fwo));
-- select #fwo,#len;
set #sl = 1;
if #len >0 then
increment: repeat
set #valu = SUBSTRING(#fwo, #sl , 1);
set #valu2 = SUBSTRING(#fwo2, #sl , 1);
set #jval = JSON_OBJECT('id',#valu2,'policy',#valu);
INSERT INTO `Example`(`Column1`,`Column2`) values(#valu2,#jval);
set #sl = #sl+1;
UNTIL #sl > #len END repeat increment ;
END if ;
END$$
DELIMITER ;
When the input are 1,2,3 and a,b,c the insertion is happening correctly, but when we pass 11,12,13 and ab,cd,ef the insertion is happening likethe above condition inputs.The same repetes when the lenght increases more than 1.
Can someone suggestion me to solve this issue

count total even and odd number between 20-50 with mysqll procedure

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)

mysql select into returns NULL

Please help me understand,
I need to make stored procedure for creating new user into db.
delimiter //
CREATE PROCEDURE add_user (x VARCHAR(25))
BEGIN
DECLARE x VARCHAR(25) DEFAULT 'mark';
DECLARE newname VARCHAR(25);
DECLARE xid INT;
SELECT x, id INTO newname, xid
FROM users WHERE x = x;
SELECT newname;
END;
delimiter ;
when i call add_user('peter');
it shows me:
newname/null
where do i go wrong ?
CREATE PROCEDURE add_user (x VARCHAR(25))
BEGIN
DECLARE x VARCHAR(25) DEFAULT 'mark';
This actually creates two variables named x. The first is the function parameter, and the second is a local variable which is in scope inside the BEGIN ... END block. According to MySQL's scoping rules, only one of these variables can be visible, which means that the parameter x is hidden and inaccessible inside the BEGIN ... END block.
The solution is simply to delete the line
DECLARE x VARCHAR(25) DEFAULT 'mark';
and, if you need to assign a default value, do it in an IF block:
IF x IS NULL THEN
SET x = 'mark';
END IF;
The complete function definition should be
delimiter //
CREATE PROCEDURE add_user (x VARCHAR(25))
BEGIN
DECLARE newname VARCHAR(25);
DECLARE xid INT;
IF x IS NULL THEN
SET x = 'mark';
END IF;
SELECT x, id INTO newname, xid
FROM users WHERE x = x;
SELECT newname;
END;
delimiter ;

In a MySQL select statement, can I split a text column and then sum the parts as floats?

I have a MySQL column that is defined as text. The column, if not null, always contains a list floats separated by a newline character.
I have been tasked with making the total amount of those floats searchable with min and max constraints.
In the where clause, I would like to be able split the column by a newline character and sum all of the resulting strings as floats.
Is this possible?
You may have to define your own function.Here is an example I just tested, hope it is helpful to you(BTW: It is not advisable to implement such kind of functions in mysql. Maybe it is better to let the application servers to compute it instead of mysql :)).
DELIMITER $$
CREATE function split_n_sum(str text) returns DECIMAL(36,4)
begin
declare location int;
declare result decimal(36,4);
declare tmp_str varchar(1024);
declare _delimiter varchar(128);
set _delimiter='\r\n';
set result=0;
set tmp_str=ltrim(rtrim(str));
set location=INSTR(tmp_str,_delimiter);
if location=0 and length(tmp_str)>0 then
set result=cast(tmp_str as decimal(36,4));
set tmp_str='';
end if;
while location<>0 do
set result = result+cast(substring(tmp_str,1,location-length(_delimiter)) as decimal(36,4));
set tmp_str=substring(tmp_str,location+length(_delimiter), length(tmp_str));
set location=INSTR(tmp_str,_delimiter);
end while;
if length(tmp_str)>0 then
set result=result+cast(tmp_str as decimal(36,4));
end if;
return result;
end$$
Yes, you can: Use a function:
CREATE FUNCTION splitAndSum(inputStr VARCHAR)
RETURNS FLOAT;
BEGIN
DECLARE summedValues FLOAT;
DECLARE tempVal FLOAT;
DECLARE subString VARCHAR(200);
DECLARE tempLength INT;
SET subString=inputStr;
SET tempLength=0;
WHILE(TRUE) DO;
SET splitStr=MID(0,instr(subString," "));
SET tempLength=length(subString);
SET subString=MID(instr(subString," "));
SET tempVal=CAST(splitStr AS FLOAT);
SET tempVal=CAST(splitStr AS FLOAT);
SET summedValues=summedValues+tempVal;
IF(length(subString)==tempLength) break;
DONE;
RETURN summedValues;
END;
Call the function:
SELECT splitAndSum("1 2 3");
Should return: 6
Function needs to be tested...