I am studying mysql. Here is my code of practicing stored procedure.
CREATE DEFINER=`raxuser`#`%` PROCEDURE `test`(in fc_frm_date char(5), in fc_to_date char(5))
BEGIN
declare frm_date char(5);
declare to_date char(5);
select fc_frm_date into #frm_date;
select fc_to_date into #to_date;
select distinct #frm_date, #to_date, fc_frm_date, fc_to_date;
set #s = CONCAT('select distinct #frm_date, #to_date, fc_frm_date, fc_to_date;');
PREPARE stmt FROM #s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END
When I run it , the first select query get correct while the second one shows error code as
Error Code: 1054 Unknown column 'fc_frm_date' in 'field list'
I thought the two select queries should be equal but not. Can anyone help to explain?
Many thanks.
I think the right way to do this (UNTESTED) is:
set #s = CONCAT('select distinct ? , ? , ? , ?;');
PREPARE stmt FROM #s;
EXECUTE stmt USING #frm_date, #to_date, fc_frm_date, fc_to_date;
DEALLOCATE PREPARE stmt;
Try it:
CREATE DEFINER=`raxuser`#`%` PROCEDURE `test`(fc_frm_date char(5), fc_to_date char(5))
BEGIN
DECLARE frm_date CHAR(5);
DECLARE to_date CHAR(5);
SELECT fc_frm_date INTO #frm_date;
SELECT fc_to_date INTO #to_date;
SELECT fc_frm_date INTO #fc_frm_date;
SELECT fc_to_date INTO #fc_to_date;
SET #s = 'select distinct #frm_date, #to_date, #fc_frm_date, #fc_to_date';
PREPARE stmt FROM #s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SELECT #s;
END
Related
In the procedure I'm writing I need to store the result of a dynamic SQL query into a local variable. Something like this:
DELIMITER //
CREATE PROCEDURE test_maxsum(uid varchar(25))
BEGIN
DECLARE maxsum int;
SET #SQL = CONCAT('SELECT MAX(sum_val) FROM ', uid);
PREPARE stmt FROM #SQL;
EXECUTE stmt INTO maxsum;
DEALLOCATE PREPARE stmt;
SELECT maxsum;
END//
DELIMITER ;
Local variables cannot be assigned in prepared statements. You can use user-defined variables though:
DELIMITER //
CREATE PROCEDURE test_maxsum(uid varchar(25))
BEGIN
SET #SQL = CONCAT('SELECT MAX(sum_val) INTO #maxsum FROM ', uid);
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT #maxsum;
END//
DELIMITER ;
Having trouble with this stored procedure. Been at it for at least 4 hours, and still, no luck.
It creates the procedure no problem, but, when trying to call it, it throws a syntax error with no clues where to find the mistake. (Syntax error near '').
I'm using MySQL 5.6.39, and as client, HeidiSQL 9.5.0.5196
Edit: The purpose of this procedure, is to calculate the average time from another table, ignoring the outliers, that's why I used so many temp tables.
Thanks again!
Here's the code
DROP PROCEDURE IF EXISTS tiempoPromedioUsuarioP;
DELIMITER //
CREATE PROCEDURE tiempoPromedioUsuarioP (IN current_user_id INT, IN outliers FLOAT(4,3), OUT promedio_segundos INT)
BEGIN
DECLARE done INT DEFAULT FALSE;
SET #s1 = CONCAT('CREATE TEMPORARY TABLE tp',current_user_id, ' (SELECT TIMESTAMPDIFF(SECOND, sesion_log.init_date, sesion_log.end_date) AS tiempoPromedio FROM sesion_log WHERE sesion_log.id_usuario = ', current_user_id, ' AND sesion_log.is_end = 1;');
PREPARE stmt1 FROM #s1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET #s2 = CONCAT('CREATE TEMPORARY TABLE boundsA',current_user_id,' (SELECT (AVG(tp',current_user_id,'.tiempoPromedio) - STD(tp',current_user_id,'.tiempoPromedio)*',outliers,') AS lb FROM tp',current_user_id,');');
PREPARE stmt2 FROM #s2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET #s3 = CONCAT('CREATE TEMPORARY TABLE boundsB',current_user_id,' (SELECT (AVG(tp',current_user_id,'.tiempoPromedio) + STD(tp',current_user_id,'.tiempoPromedio)*',outliers,') AS ub FROM tp',current_user_id,');');
PREPARE stmt3 FROM #s3;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
SET #s4 = CONCAT('CREATE TEMPORARY TABLE res',current_user_id,' SELECT round(AVG(tp',current_user_id,'.tiempoPromedio)) as promedio FROM tp WHERE tp',current_user_id,'.tiempoPromedio BETWEEN (SELECT lb FROM boundsA',current_user_id,') AND (SELECT ub FROM boundsB',current_user_id,');');
PREPARE stmt4 FROM #s4;
EXECUTE stmt4;
DEALLOCATE PREPARE stmt4;
SET #s5 = CONCAT('
DECLARE promedioc CURSOR FOR SELECT * FROM res',current_user_id,';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN promedioc;
read_loop: LOOP
FETCH promedioc INTO promedio_segundos;
IF done THEN
LEAVE read_loop;
END IF;
END LOOP;
CLOSE promedioc;
');
PREPARE stmt5 FROM #s5;
EXECUTE stmt5;
DEALLOCATE PREPARE stmt5;
SET #s6 = CONCAT('DROP TEMPORARY TABLE tp',current_user_id);
PREPARE stmt6 FROM #s6;
EXECUTE stmt6;
DEALLOCATE PREPARE stmt6;
SET #s7 = CONCAT('DROP TEMPORARY TABLE boundsA',current_user_id);
PREPARE stmt7 FROM #s7;
EXECUTE stmt7;
DEALLOCATE PREPARE stmt7;
SET #s8 = CONCAT('DROP TEMPORARY TABLE boundsB',current_user_id);
PREPARE stmt8 FROM #s8;
EXECUTE stmt8;
DEALLOCATE PREPARE stmt8;
SET #s9 = CONCAT('DROP TEMPORARY TABLE res',current_user_id);
PREPARE stmt9 FROM #s9;
EXECUTE stmt9;
DEALLOCATE PREPARE stmt9;
END//
DELIMITER ;
Thanks for your help!
I have a procedure like this
set #dt=now();
SET #query = CONCAT('insert into tbl_Name (Name , Created_Date , Created_By) values (?,?,?)');
PREPARE stmt FROM #sql;
EXECUTE stmt using #tbl_column_value, #dt, #tbl_user_id;
END IF;
DEALLOCATE PREPARE stmt;
im getting this error
java.sql.SQLException: Incorrect arguments to EXECUTE
1)Below is the code I'm trying for a procedure where I need to compare the count from two different tables. (tbl1 and tbl2 are in parameters to be passed).
But in the above code the values for 'a' and 'b' are set as statements. I need the resultant value(count) from the two statements to compare in the 'IF' condition.
declare a integer;
declare b integer;
set #a:=concat('select count(*) from ', tbl1);
/*PREPARE stmt1 FROM #a;
execute stmt1;
deallocate PREPARE stmt1;*/
set #b:= concat('select count(*) from ', tbl2);
/*PREPARE stmt2 FROM #b;
execute stmt2;
deallocate PREPARE stmt2;*/
if
#a=#b
then
select 1;
else
select 2;
end if;
2) Actually where I am facing a problem to set 'tbl1' and 'tbl2' as parameters in procedure.
The below code works fine if the table names are given directly, but i need them as parameters.
CREATE PROCEDURE myproc (in tbl1 varchar(50), in tbl2 varchar(50))
declare a integer;
declare b integer;
set #a:=(select count(*) from tbl1);
/*PREPARE stmt1 FROM #a;
execute stmt1;
deallocate PREPARE stmt1;*/
set #b:= (select count(*) from tbl2);
/*PREPARE stmt2 FROM #b;
execute stmt2;
deallocate PREPARE stmt2;*/
if
#a=#b
then
select 1;
else
select 2;
end if;
Hope anyone out there can help me with the solution.
As mentioned in the comments above, it is likely that you shouldn't be doing this at all... but, for what it's worth:
SET #sql := CONCAT('SELECT (
SELECT COUNT(*) FROM `',REPLACE('`','``',tbl1),'`
) = (
SELECT COUNT(*) FROM `',REPLACE('`','``',tbl2),'`
);');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #sql := NULL;
REPLACE() has been used to try and avoid SQL injection (it's somewhat crude, but it's the best one can do without further information).
My current code is :
DELIMITER \\
CREATE PROCEDURE sample (IN _car VARCHAR(15))
BEGIN
DECLARE _a INTEGER;
SET #s = CONCAT('SELECT COUNT(*) FROM train WHERE ', _car, '<=0;');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END\\
But I wanted to capture the answer of the SELECT statement to my _a variable.
I tried changing my code to
SET #s = CONCAT('SELECT COUNT(*) INTO', _a,' FROM train WHERE ', _car, '<=0;');
But that didn't work.
Help, please?
SOLVED!
DELIMITER \\
CREATE PROCEDURE sample (IN _car VARCHAR(15))
BEGIN
DECLARE _a INTEGER;
SET #var = NULL;
SET #s = CONCAT('SELECT COUNT(*) INTO #var FROM train WHERE ', _car, '<=0;');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
SELECT #var;
DEALLOCATE PREPARE stmt1;
END\\
:D
As stated here you need to include the variable assignment in the original statement declaration. So you statement would be something like:
SELECT COUNT(*) FROM train WHERE ?<=0 INTO _a
Then you you would execute it with:
EXECUTE stmt1 using _car;
And get the result with:
select _a;
Let me know if it works.