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
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 ;
if I want to call a procedure with different input in each time input1,input2, input 3, ... and different output out1,out2,...and so on
proc(input1,out1) proc(input2,out2)...
can I made only one prepared statement inside a while loop to do that job? something like this
while c <= 10 DO
SET #sql = CONCAT('call proc(input',c,',out',c')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set c=c+1;
end while;
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 am trying to run the dynamic query using a stored procedure in which I am sending the where condition case for example.
My sample stored procedure is shown here:
CREATE PROCEDURE `Storedproc`(IN getwhereconditon varchar(1000))
BEGIN
set #param=getwhereconditon ;
SET #S=concat('Select * from table where (1)',#param);
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
END
Here my stored procedure's name is Storedproc in which I am passing the where condition details and when I call my stored procedure I am getting this error
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '0tablecol=1' at line
Try
DELIMITER //
CREATE PROCEDURE myproc(IN _where VARCHAR(512))
BEGIN
SET #sql = 'SELECT * FROM table1';
IF COALESCE(_where, '') <> '' THEN
SET #sql = CONCAT(#sql, ' WHERE ', _where);
END IF;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
or
DELIMITER //
CREATE PROCEDURE myproc(IN _where VARCHAR(512))
BEGIN
SET #sql = CONCAT('SELECT * FROM table1', COALESCE(CONCAT(' WHERE ', NULLIF(_where, '')), ''));
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
Sample usage:
CALL myproc(NULL);
CALL myproc('name=''John''');
CALL myproc('age > 25');
CALL myproc('age < 28 OR age > 30');
Here is SQLFiddle demo
Although there are some good examples of multiple parameters being used in MySQL stored procedures, I have been unable to find a simple example that shows how to use them in a stored procedure that is prepared.
The code below returns 'Incorrect arguments to EXECUTE' when calling it using: `call test_parms('my report','example.com');
I've tried with and without '#' in front of the parameter names (just gives an unknown column error), and different variations of the code . What am I doing wrong?
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `test_parms`(REPORT VARCHAR(255),DOMAIN_NAME VARCHAR(255))
BEGIN
SET #sql = "Select #DOMAIN_NAME,#REPORT";
set #REPORT=REPORT;
set #DOMAIN_NAME=DOMAIN_NAME;
PREPARE stmt FROM #sql;
EXECUTE stmt using #DOMAIN_NAME,#REPORT;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
The following section of the documentation will be helpful: 13.5.1. PREPARE Syntax.
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE PROCEDURE `test_parms`(`REPORT` VARCHAR(255), `DOMAIN_NAME` VARCHAR(255))
BEGIN
SET #`sql` := 'SELECT ? `DOMAIN_NAME`, ? `REPORT`';
SET #`REPORT` := `REPORT`;
SET #`DOMAIN_NAME` := `DOMAIN_NAME`;
PREPARE `stmt` FROM #`sql`;
EXECUTE `stmt` USING #`DOMAIN_NAME`, #`REPORT`;
DEALLOCATE PREPARE `stmt`;
END$$
DELIMITER ;
SQL Fiddle demo
UPDATE
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE PROCEDURE `test_parms`(`REPORT` VARCHAR(255), `DOMAIN_NAME` VARCHAR(255))
BEGIN
SELECT `DOMAIN_NAME` `DOMAIN_NAME`, `REPORT` `REPORT`;
END$$
DELIMITER ;
SQL Fiddle demo
Looks like I was unnecessarily setting user defined variables prior to execution, which was included in some of the stored procedure examples, but apparently doesn't work if the stored procedure is prepared.
To fix, Replace the following code:
set #REPORT=REPORT;
set #DOMAIN_NAME=DOMAIN_NAME;
PREPARE stmt FROM #sql;
EXECUTE stmt using #DOMAIN_NAME,#REPORT;
with this :
PREPARE stmt FROM #sql;
EXECUTE stmt;
So the corrected code looks like:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `test_parms`(REPORT VARCHAR(255),DOMAIN_NAME VARCHAR(255))
BEGIN
SET #sql = "Select #DOMAIN_NAME,#REPORT";
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Update
I ended up with the following which works with any user with privileges to execute procedures ('process' permission is not required like it is for the previous code) and works correctly on SQL Fiddle:
DROP PROCEDURE IF EXISTS `test_parms`//
CREATE PROCEDURE `test_parms`(REPORT VARCHAR(255),DOMAIN_NAME VARCHAR(255))
BEGIN
SET #sql = "Select #DOMAIN_NAME,#REPORT";
SET #DOMAIN_NAME=DOMAIN_NAME;
SET #REPORT=REPORT;
PREPARE stmt FROM #sql;
EXECUTE STMT;
DEALLOCATE PREPARE STMT ;
END//
SQL Fiddle - Updated Final