MySQl storage procedures - mysql

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;

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 stored procedure return value

I have to create an SP that returns a value if it's valid or not. But it doesn't return anything and I don't know, why?
CREATE DEFINER=`root`#`localhost` PROCEDURE `validar_egreso`(
IN codigo_producto VARCHAR(100),
IN cantidad INT,
OUT valido INT(11)
)
BEGIN
DECLARE resta INT(11);
SET resta = 0;
SELECT (s.stock - cantidad) INTO resta
FROM stock AS s
WHERE codigo_producto = s.codigo;
IF (resta > s.stock_minimo) THEN
SET valido = 1;
ELSE
SET valido = -1;
END IF;
SELECT valido;
END
You have done the stored procedure correctly but I think you have not referenced the valido variable properly. I was looking at some examples and they have put an # symbol before the parameter like this #Valido
This statement SELECT valido; should be like this SELECT #valido;
Look at this link mysql stored-procedure: out parameter. Notice the solution with 7 upvotes. He has reference the parameter with an # sign, hence I suggested you add an # sign before your parameter valido
I hope that works for you. if it does vote up and mark it as the answer. If not, tell me.
Add:
DELIMITER at the beginning and end of the SP.
DROP PROCEDURE IF EXISTS validar_egreso; at the beginning
When calling the SP, use #variableName.
This works for me. (I modified some part of your script so ANYONE can run it with out having your tables).
DROP PROCEDURE IF EXISTS `validar_egreso`;
DELIMITER $$
CREATE DEFINER='root'#'localhost' PROCEDURE `validar_egreso` (
IN codigo_producto VARCHAR(100),
IN cantidad INT,
OUT valido INT(11)
)
BEGIN
DECLARE resta INT;
SET resta = 0;
SELECT (codigo_producto - cantidad) INTO resta;
IF(resta > 1) THEN
SET valido = 1;
ELSE
SET valido = -1;
END IF;
SELECT valido;
END $$
DELIMITER ;
-- execute the stored procedure
CALL validar_egreso(4, 1, #val);
-- display the result
select #val;
Update your SP and handle exception in it using declare handler with get diagnostics so that you will know if there is an exception.
e.g.
CREATE DEFINER=`root`#`localhost` PROCEDURE `validar_egreso`(
IN codigo_producto VARCHAR(100),
IN cantidad INT,
OUT valido INT(11)
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
#p1 = RETURNED_SQLSTATE, #p2 = MESSAGE_TEXT;
SELECT #p1, #p2;
END
DECLARE resta INT(11);
SET resta = 0;
SELECT (s.stock - cantidad) INTO resta
FROM stock AS s
WHERE codigo_producto = s.codigo;
IF (resta > s.stock_minimo) THEN
SET valido = 1;
ELSE
SET valido = -1;
END IF;
SELECT valido;
END

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)

can't get MySQL query to work

I am trying to create a stored procedure on a Library database for practice mainly.
But it is confusing me slightly. I am using this query to create the procedure, and it says that it is working, and yet when I then call the procedure, it is saying that the procedure does not exist. Note: I am using phpmyadmin on a web database not on a local host.
delimiter $$
create procedure BorrowBook(in theBookID, in theUserID)
begin
declare lim int;
declare num int;
declare loanNumber int;
declare copyNumber int;
set lim = (select Readers.Limit from Readers where Readers.id = theUserID);
set num = (select Count(*) from Loans where Loans.UserID = theUserID);
set loanNumber = (select Count(*) from Loans) + 1;
set copyNumber = (select NumberAvailable from Book where Book.id = theBookID);
if(copyNumber > 0)
if(num<lim)
then
--Add a Loan to the Loans Table
insert into Loans values(loanNumber, theBookId, theUserID, curDate(), 0);
commit;
update Book set Book.NumberAvailable = Book.NumberAvailable - 1 where Book.id = theBookID;
select 'Succesful Update';
else
rollback;
select 'Borrow limit reached';
end if;
else
rollback;
select 'No copies available';
end;
delimiter ;
You are missing the $$ after the last end:
delimiter $$
...
end; $$ <-- add $$ here
delimiter ;
Shouldn't it be
end; $$
delimiter ;
instead of
end;
delimiter ;

Mysql stored procedure multiple selects

I am running a stored procedure. The issue seems to be that it will go into the if statement. Also for some reason or another regardless of how many selects I use it will only return the first. I've copied this from another stored procedure that works like a charm, but this one just won't go. Any ideas?
DROP PROCEDURE IF EXISTS genSelPriceTier;
DELIMITER $$
CREATE PROCEDURE genSelPriceTier(tier_id INT, default_id INT)
BEGIN
DECLARE rowCount INT DEFAULT 0;
SELECT * FROM price_tier WHERE price_tier_id = tier_id;
SET rowCount = FOUND_ROWS();
IF rowCount < 1 THEN
SELECT * FROM price_tier WHERE price_tier_id = default_id;
END IF;
END$$
DELIMITER ;
There is a bug reported related to the usage of FOUND_ROWS(). So, I recommend using Count(*) for the number of rows returned. Something like the following should work.
DROP PROCEDURE IF EXISTS genSelPriceTier;
DELIMITER $$
CREATE PROCEDURE genSelPriceTier(tier_id INT, default_id INT)
BEGIN
DECLARE rowCount INT DEFAULT 0;
SELECT COUNT(*) INTO rowCount FROM price_tier WHERE price_tier_id = tier_id
IF rowCount < 1 THEN
SELECT * FROM price_tier WHERE price_tier_id = default_id;
END IF;
END$$
DELIMITER ;