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!
How do I create a table in my schema using the current date or timestamp as the naming convention?
CREATE Table CURRENT_DATE|TIMESTAMP;
REPLACE CURRENT_DATE|TIMESTAMP
SELECT *
FROM other.othertable;
I managed to solve it, for those interested.
SET #YYYY_MM_DD_HH_MM_SS=date_format((SELECT NOW() FROM DUAL),'%Y-%m-%d %h:%m:%s');
SET #c = CONCAT('CREATE TABLE `new`.`',#YYYY_MM_DD_HH_MM_SS, '` LIKE `old`.`oldtable`');
PREPARE stmt from #c;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #u = concat('REPLACE `new`.`',#YYYY_MM_DD_HH_MM_SS, '` SELECT * FROM `old`.`oldtable`');
PREPARE stmt2 from #u;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
i am trying to write a stored procedure which updates the field of a table as specified in the argument .i am getting syntax error in #sql statment.please help
create procedure new_upd1(ind int(3),attribute varchar(30),pk int(11),new_value varchar(30))
begin
set #att=attribute;
set #primk=pk;
set #updated=new_value;
if ind=1 then
set #sql='update department set ?=? where departmentid=?';
prepare stmt from #sql;
execute stmt using #att,#updated,#primk;
deallocate prepare stmt;
end if;
end
Parameters don't work for column or table names, only for values. Do it like this:
create procedure new_upd1(ind int(3),attribute varchar(30),pk int(11),new_value varchar(30))
begin
set #att=attribute;
set #primk=pk;
set #updated=new_value;
if ind=1 then
set #sql=CONCAT('update department set ', #att, '=? where departmentid=?;');
prepare stmt from #sql;
execute stmt using #updated,#primk;
deallocate prepare stmt;
end if;
end
can i somehow set parameter for name of table in query without using a prepare statement?
This is example:
SET #tableName = 'Customer';
SELECT * FROM #tableName;
Thanks
Depending on the version of MySQL you are using, you may be able to use something like:
SET #tableName = 'Customer';
SET #s = CONCAT('SELECT * FROM ', #tableName);
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;