mysql select into returns NULL - mysql

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 ;

Related

Using Loop and Cursor in same mysql procedure showing error

The following code is working properly. But when i am enabling the commented area (cursor), then the code showing error. Please help to fix the issue.
Scenario: The code allow some parameter. It will prepare the data in a table and then the cursor will take data from that table and output that data.
Same Parameter: call prGetInsuranceData_Multiple(2, 'Saroar,Ahmed', '20,30')
DELIMITER $$
USE `surokkha_db`$$
DROP PROCEDURE IF EXISTS `prGetInsuranceData_Multiple`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `prGetInsuranceData_Multiple`
(
PeopleToBeCovered INT,
IN NAME VARCHAR(4000),
IN AGE VARCHAR(200)
)
BEGIN
-- declare loop variables
DECLARE V_Name VARCHAR(255);
DECLARE V_AGE INT;
DECLARE X INT DEFAULT 0;
-- declare cursor variables
DECLARE Cur_Finished INTEGER DEFAULT 0;
DECLARE Cur_Name VARCHAR(255);
DECLARE Cur_Age INT;
-- create a table with comma separated values (Name with age in table format)
CREATE TEMPORARY TABLE TempCustomer
(
NAME VARCHAR(255),
AGE INT
);
CREATE TEMPORARY TABLE TempCustomer1
(
NAME VARCHAR(255),
AGE INT
);
SET X = 1;
BEGIN
WHILE X <= PeopleToBeCovered DO
SET V_Name = SUBSTRING_INDEX(SUBSTRING_INDEX(NAME,',',X),',',-1);
SET V_Age = SUBSTRING_INDEX(SUBSTRING_INDEX(AGE,',',X),',',-1);
SET X = X + 1;
INSERT INTO TempCustomer VALUES(V_Name, V_Age);
END WHILE;
END;
/*
-- declare cursor
DECLARE cur_NameWithAge
CURSOR FOR
SELECT NAME, AGE FROM TempCustomer;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
OPEN cur_NameWithAge;
GetNameWithAge: LOOP
FETCH cur_NameWithAge INTO Cur_Name, Cur_Age;
IF finished = 1 THEN
LEAVE GetNameWithAge;
END IF;
-- get data and insert into table
INSERT INTO TempCustomer1 VALUES(Cur_Name, Cur_Age);
END LOOP GetNameWithAge;
CLOSE cur_NameWithAge;
*/
SELECT * FROM TempCustomer;
-- as after setting cursor the data is not needed, thats why drop the tables
DROP TEMPORARY TABLE TempCustomer;
DROP TEMPORARY TABLE TempCustomer1;
END$$
DELIMITER ;
You need to pout the loop and its declarations in a BEGIn ENd
Still i needed to reprogram the hole thing, because your code threw error, that i couldn't find
create procedure prGetInsuranceData_Multiple(
IN PeopleToBeCovered INT,
IN _NAME VARCHAR(4000),
IN _AGE VARCHAR(200))
begin
DECLARE V_Name VARCHAR(255);
DECLARE V_AGE INT;
DECLARE X INT DEFAULT 0;
drop temporary table if exists TempCustomer;
drop temporary table if exists TempCustomer1;
create temporary table TempCustomer( NAME VARCHAR(255),AGE int );
create temporary table TempCustomer1(NAME VARCHAR(255),AGE int);
SET X = 1;
BEGIN
WHILE X <= PeopleToBeCovered DO
SET V_Name = SUBSTRING_INDEX(SUBSTRING_INDEX(_NAME,',',X),',',-1);
SET V_Age = SUBSTRING_INDEX(SUBSTRING_INDEX(_AGE,',',X),',',-1);
SET X = X + 1;
INSERT INTO TempCustomer VALUES(V_Name,V_Age);
END WHILE;
END;
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE v_id int ;
DECLARE v_name varchar(255);
declare cur_NameWithAge cursor for select NAME,AGE from TempCustomer;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
open cur_NameWithAge;
GetNameWithAge: LOOP
fetch cur_NameWithAge into v_name,v_id;
IF finished = 1 THEN
LEAVE GetNameWithAge;
END IF;
INSERT INTO TempCustomer1 VALUES (v_name,v_id);
END LOOP GetNameWithAge;
CLOSE cur_NameWithAge;
END;
select * FROM TempCustomer;
DROP TEMPORARY TABLE TempCustomer1;
DROP TEMPORARY TABLE TempCustomer1;
end
call prGetInsuranceData_Multiple(2, 'Saroar,Ahmed', '20,30')
NAME | AGE
:----- | --:
Saroar | 20
Ahmed | 30
db<>fiddle here

MySQL build a variable name?

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 ;

IF/ELSE structure in mysql SP not working

I have written a stored procedure which enrols a student in a table. But before doing so, it checks weather the student is already present, if it does then no insertion takes place.
DELIMITER //
CREATE PROCEDURE test(IN sid varchar(6), IN us varchar(20), IN pswd varchar(20))
BEGIN
declare temp varchar(20);
declare x int;
declare y int;
set temp=(select username from login_student where s_id=sid);
IF(temp == NULL)
THEN insert into login_student values(sid, us, pswd);
ELSEIF (temp != NULL)
THEN set x=x+1; //have written it randomly
ELSE
set y=y+1; //have written it randomly
END IF;
END //
DELIMITER ;
login_student table schema is defined as:
CREATE TABLE login_student
(s_id varchar(6),
username varchar(20),
password varchar(20)
);
It's giving me some syntax error, can any one mark out the mistake please?
Two problems I see:
You need to use IS NULL and IS NOT NULL instead of == NULL and != NULL
You are using the wrong syntax for MySQL comments. Use -- not //
It should also be noted that you will never reach the ELSE in this case, since temp is either NULL or NOT NULL, so you could simplify it to an IF/ELSE if you want.
And I would recommend using SELECT ... INTO instead of SET to set the temp value.
Putting it all together:
DELIMITER //
DROP PROCEDURE IF EXISTS test //
CREATE PROCEDURE test(IN sid varchar(6), IN us varchar(20), IN pswd varchar(20))
BEGIN
declare temp varchar(20);
declare x int;
declare y int;
select username into temp from login_student where s_id=sid;
IF(temp IS NULL)
THEN insert into login_student values(sid, us, pswd);
ELSEIF (temp IS NOT NULL)
THEN set x=x+1; -- have written it randomly
ELSE
set y=y+1; -- have written it randomly
END IF;
END //
DELIMITER ;
Would be nice to get the text of an error, but I think it should be:
IF(temp IS NULL)
THEN insert into login_student values(sid, us, pswd);
ELSEIF (temp IS NOT NULL)
THEN set x=x+1; //have written it randomly
ELSE
set y=y+1; //have written it randomly
END IF;

MYSQL function, is it Workbench or just noobish me?

I have been sitting with a stored procedure for MySQL for days now, it just won't work, so I thought I'd go back to basic and do a very simple function that checks if an item exists or not.
The problem I had on the first one was that it said END IF is invalid syntax on one of my IF clauses, but not the other two. The second one won't even recognize BEGIN as valid syntax...
Is it I that got everything wrong, or have I stumbled upon a MYSQL Workbench bug? I have Workbench 5.2 (latest version when I'm writing this) and this is the code:
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT)
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
to fix the "begin" syntax error, you have to declare a return value, like this:
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT) RETURNS INT(11)
after doing that, Workbench won't return an error anymore ;o)
You have to specify the return value in signature as well delimiter at the end is missing. So, your function should look like
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT) RETURNS INT
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
$$
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT)
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
$$
DELIMITER ;
Add this last thing it works :
$$
DELIMITER ;
it means you are using ( ; ) this in function so for that reason we use it..see
and see also
MySQL - Trouble with creating user defined function (UDF)

MySQl storage procedures

I have a little problem. Looks like the procedure does not exist. Somehow it's dropped after the creation. I get different error each time i change something. I'm not really sure what's causing the error, maybe I'm not allowed to drop procedures and creating them in the same query.
I hope you guys can help me out.
drop procedure if exists refIntChk;
DELIMITER //
CREATE PROCEDURE refIntChk(IN district INT(11), OUT b INT(1))
BEGIN
DECLARE b INT(1);
IF district IN (select dist FROM t13)
THEN
SET b = 1;
ELSE
SET b = 0;
END IF;
END; //
DELIMITER ;
drop procedure gen if exists ;
DELIMITER //
CREATE PROCEDURE gen()
BEGIN
DECLARE rows INT(11) DEFAULT (SELECT COUNT(dist) FROM t13);
DECLARE district INT(11);
DECLARE custname VARCHAR(16);
DECLARE revenue FLOAT;
DECLARE x INT DEFAULT 10000;
DECLARE outvar INT(11);
WHILE x > 0
DO
SET district = FLOOR(RAND()*rows)+1;
CALL refIntChk(district, outvar);
IF outvar = 1
THEN
SET custname = substring(MD5(RAND()), -16);
SET revenue = (RAND() * 10);
INSERT INTO t14 VALUES(NULL, custname, district, revenue);
SET x = x - 1;
END IF;
END WHILE;
END;//
DELIMITER ;
CALL gen();
When you get errors, it's usually good to run each statement, one by one, and see which one is producing the error.
The second DROP procedure statement should be:
drop procedure if exists gen;