Prepared Statement query syntax error - mysql

Please can anyone tell me why this stored procedure is not working , what am I doing wrong.It keeps giving syntax error.
puserid and plimit are the parameters passed in the procedure.
DECLARE uid BIGINT;
DECLARE rangee TINYINT;
SET #uid = puserid;
SET #rangee = plimit * 15;
PREPARE STMT FROM
'IF((SELECT count(type) from notificationrecievers nr where
nr.status=0 and nr.recieverid=?) = 0) THEN
select nr.type,n.senderid,n.postid,u.name,nr.status
from
user u,notifications n,notificationrecievers nr where
nr.recieverid=? and u.userid=n.senderid and
nr.notificationid=n.notid order by n.notid desc
limit 15 OFFSET ?;
ELSE
select nr.type,n.senderid,n.postid,u.name,nr.status
from
user u,notifications n,notificationrecievers nr where
nr.recieverid=? and u.userid=n.senderid and nr.status=0 and
nr.notificationid=n.notid order by n.notid desc;
END IF;';
EXECUTE STMT USING #uid,#uid,#rangee,#uid;
Here's the error that i get.
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 'IF((SELECT count(type) from notificationrecievers nr where nr.status=0 and nr.r' at line 1

You can use only DML in prepared statements.
You can do something like this
IF condition THEN
set #q = 'your query text'
ELSE
set #q = 'another query'
END IF;
PREPARE stmt FROM #q
EXECUTE stmt using ...
DEALLOCATE PREPARE stmt
You can execute some queries before to evaluate your conditions.
Hope it helps

Related

is there any way to use if-else statement in mysql other than sp and functions?

is there any way to use if-else statement in mysql outside sps and functions in ad hoc queries? It can be easily done is MS SQL.
This is my query:
SET #Flag := 'u', #appUserID := 0;
SELECT app_user_id
INTO #appUserID
FROM app_user
WHERE user_login_id = #UserLoginID;
IF #Flag = 'u' THEN
SELECT #appUserID;
END IF;
I receive 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 'IF #Flag = 'u' THEN SELECT #appUserID' at line 1"
Running this in a normal query tab, you can use DDL
SET #Flag := 'u', #appUserID := 0;
SELECT app_user_id
INTO #appUserID
FROM app_user
WHERE user_login_id = #UserLoginID;
SELECT IF(#Flag = 'u',#sql := "SELECT #appUserID; ",#sql := "DO NULL");
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

How to put limit in select statement in inner query while inserting in temp table

I want to make a query which insert data from another table with a dynamic limit which generate on run time how can i do this
This is a part of a procedure where i am inserting data in temp table for a session so i can process other queries, I have done that by repeat statement but that takes longer time then expected i want something like this but MySQL does not allow variable in limit.
I am using int here for demo purpose.
**SET #counter = 10; #FOUND_ROWS();
SET #bill_id = 1; #last_insert_id();
INSERT INTO billingids (bill_id) (
SELECT id from cfx_billing WHERE id >= #bill_id LIMIT #counter
);**
But it is not working Then i have tried prepare statement
**SET #counter = 10; #FOUND_ROWS();
SET #bill_id = 1; #last_insert_id();
PREPARE STMT FROM "SELECT id from cfx_billing WHERE id >= #bill_id LIMIT ?";
INSERT INTO billingids (bill_id) (
EXECUTE STMT USING #counter
);
DEALLOCATE PREPARE stmt;**
For 1 statement i am getting this error
SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '#counter
)' at line 1.
For 2 statement
SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'EXECUTE STMT USING #counter
)' at line 2
You can't use EXECUTE STMT inside a subquery. It has to be the whole query.
PREPARE STMT FROM "INSERT INTO billingids (bill_id)
SELECT id from cfx_billing WHERE id >= #bill_id LIMIT ?";
EXECUTE STMT USING #counter;
I've not tested this example, but I know that you need to prepare the whole statement, not just the subquery.

MYSQL - Execute procedure to execute statement from table

I am working in a stored procedure that is fetching queries from a table and execute them.
The problem is that I have some queries with single/doubled quotes and it is throwing an error on execute them.
Procedure
delimiter $$
drop procedure if exists run_change_ids_queries$$
create procedure run_change_ids_queries()
begin
declare s_query TEXT;
declare done bool default false;
declare c_queries cursor for
select `query` from `queries` WHERE `executed` = 0 ORDER BY `qry_id` ASC;
declare continue handler for not found set done = true;
open c_queries;
read_loop: loop
fetch c_queries into s_query;
if done then
leave read_loop;
end if;
-- run the query
set #sql = s_query;
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;
-- update executed flag on query
set #update = CONCAT('UPDATE `queries` SET `executed` = 1 WHERE `query` LIKE \'',#sql,'\';');
prepare stmt from #update;
execute stmt;
deallocate prepare stmt;
end loop;
end$$
Query update urisegments as s inner join change_product_ids as p on concat('{"product_id":"', p.old_id, '"}') = s.primary_key_value set s.primary_key_value = CONCAT('{"product_id":', p.new_id, '"}') where s.app_namespace = 'Shop' and s.primary_key_value like '%product_id%'; is throwing error: [42000][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 '{"product_id":"', p.old_id, '"}') = s.primary_key_value set s.primary_key_value ' at line 1
Workaround #01
I already tried to escape single/doubled quotes into \' and \" respectively, but it throws another error:
[42000][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 '\'{\"product_id\":\"\', p.old_id, \'\"}\') = s.primary_key_value set s.primary_k' at line 1.
Don't try to concatenate the query into the SQL. Prepared statements can contain placeholders, which you fill in when you use the EXECUTE statement.
set #update = 'UPDATE `queries` SET `executed` = 1 WHERE `query` = ?');
prepare stmt from #update;
execute stmt USING #sql;
The statement is not escaped.
All single/doubled quotes should be escaped.
update urisegments as s
inner join change_product_ids as p on concat(\'{\"product_id\":\"\', p.old_id, \'\"}\') = s.primary_key_value
set s.primary_key_value = CONCAT(\'{\"product_id\":\', p.new_id, \'\"}\')
where s.app_namespace = \'Shop\' and s.primary_key_value like \'%product_id%\';
Instead of testing for the query, test for its id:
... WHERE qry_id = ?
(Add that column to the initial SELECT.)

Prepared Statement Insert With Select two tables

I am using a prepared statement to insert data from table 1 into table 2 (a copy of table 1)
Only difference is table 2 has a DateTime column. I am trying to insert the data from table 1 into table 2. But how can I add the datetime(current time and date)?
I am a little suck on how to add this into my prepared statement.
DECLARE sqlquery text;
SET sqlquery = CONCAT('insert into partial_log select inaid, `PartNo`,`LineCode`,`EPartsPartNo`,`Surcharge`,`Price`,`CustomerDescription`,`ShortCode`,`PlusCode`,`LiveDate`,`CustomerPartNo`,`Alt1LineCode`,`Alt1PartNo`,`Alt1EPartsPartNo`,`Alt2LineCode`,`Alt2PartNo`,`Alt2EPartsPartNo`,`Alt3LineCode`,`Alt3PartNo`,`Alt3EPartsPartNo`,`Alt4LineCode`,`Alt4PartNo`,`Alt4EPartsPartNo`,`Alt5LineCode`,`Alt5PartNo`,`Alt5EPartsPartNo`,`Alt6LineCode`,`Alt6PartNo`,`Alt6EPartsPartNo`,`Alt7LineCode`,`Alt7PartNo`,`Alt7EPartsPartNo`,`Alt8LineCode`,`Alt8PartNo`,`Alt8EPartsPartNo`,`Alt9LineCode`,`Alt9PartNo`,`Alt9EPartsPartNo`,`Alt10LineCode`,`Alt10PartNo`,`Alt10EPartsPartNo`,',NOW(),',FROM itable order by `LineCode`,`PartNo`;');
set sqlquery=REPLACE(sqlquery,'inaid',inaid);
set sqlquery=REPLACE(sqlquery,'itable',itable);
SET #stat = sqlquery;
PREPARE stmt from #stat;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
I have tried to add Now() by using concat but this does not work and throws invalid syntax error.
#42000You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '14:00:06,FROM Ats order by LineCode,PartNo' at line 1
UPDATE:
Do not need CONCAT to add NOW() into the statement.
DECLARE sqlquery text;
SET sqlquery = 'insert into partial_log select inaid, `PartNo`,`LineCode`,`EPartsPartNo`,`Surcharge`,`Price`,`CustomerDescription`,`ShortCode`,`PlusCode`,`LiveDate`,`CustomerPartNo`,`Alt1LineCode`,`Alt1PartNo`,`Alt1EPartsPartNo`,`Alt2LineCode`,`Alt2PartNo`,`Alt2EPartsPartNo`,`Alt3LineCode`,`Alt3PartNo`,`Alt3EPartsPartNo`,`Alt4LineCode`,`Alt4PartNo`,`Alt4EPartsPartNo`,`Alt5LineCode`,`Alt5PartNo`,`Alt5EPartsPartNo`,`Alt6LineCode`,`Alt6PartNo`,`Alt6EPartsPartNo`,`Alt7LineCode`,`Alt7PartNo`,`Alt7EPartsPartNo`,`Alt8LineCode`,`Alt8PartNo`,`Alt8EPartsPartNo`,`Alt9LineCode`,`Alt9PartNo`,`Alt9EPartsPartNo`,`Alt10LineCode`,`Alt10PartNo`,`Alt10EPartsPartNo`, NOW() FROM itable order by `LineCode`,`PartNo`;';
set sqlquery=REPLACE(sqlquery,'inaid',inaid);
set sqlquery=REPLACE(sqlquery,'itable',itable);
SET #stat = sqlquery;
PREPARE stmt from #stat;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
The CONCAT is totally unnecessary, and just adding to your confusion.
Your query can be written like this
SET sqlquery = 'insert into partial_log
select inaid, `PartNo`,`LineCode`,
`EPartsPartNo`,`Surcharge`,`Price`,
`CustomerDescription`,`ShortCode`,`PlusCode`,
`LiveDate`,`CustomerPartNo`,`Alt1LineCode`,
`Alt1PartNo`,`Alt1EPartsPartNo`,`Alt2LineCode`,
`Alt2PartNo`,`Alt2EPartsPartNo`,`Alt3LineCode`,
`Alt3PartNo`,`Alt3EPartsPartNo`,`Alt4LineCode`,
`Alt4PartNo`,`Alt4EPartsPartNo`,`Alt5LineCode`,
`Alt5PartNo`,`Alt5EPartsPartNo`,`Alt6LineCode`,
`Alt6PartNo`,`Alt6EPartsPartNo`,`Alt7LineCode`,
`Alt7PartNo`,`Alt7EPartsPartNo`,`Alt8LineCode`,
`Alt8PartNo`,`Alt8EPartsPartNo`,`Alt9LineCode`,
`Alt9PartNo`,`Alt9EPartsPartNo`,`Alt10LineCode`,
`Alt10PartNo`,`Alt10EPartsPartNo`, NOW()
FROM itable order by `LineCode`,`PartNo`;');
In fact as long as the columns are all in the same order in both the partial_log and itable tabless with only the addition of the new column datetime at the end of partial_log you could write the query like this
SET sqlquery = 'insert into partial_log
SELECT a.*, NOW()
FROM itable a
ORDER BY a.LineCode,a.PartNo

Having trouble with concat in stored procedure

Can anyone tell me why I am getting this error in MySql:
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 'NULL' at line 1
Here is my code:
CREATE PROCEDURE `msgBoardGetComments2`(
IN _StoryID INT,
IN _RowNum INT
)
BEGIN
DECLARE _sql VARCHAR(1000);
SET _sql := CONCAT('SELECT c.CommentText, c.CommentDate, a.UserName
FROM comments c
LEFT JOIN accounts a
ON c.UserID = a.UserID
LEFT JOIN stories s
ON c.StoryID = s.StoryID
WHERE c.StoryID = ',_StoryID, '
ORDER BY c.CommentDate DESC
LIMIT 10
OFFSET ', _RowNum);
PREPARE stmt1 FROM #_sql;
EXECUTE stmt1;
END
I believe you may be receiving that error when _RowNum is NULL. If this is the case, you can try adding an IF condition to optionally include the OFFSET _RowNum if the _RowNum is NULL. You can test this by printing your query before execution:
SELECT _sql;
--PREPARE stmt1 FROM #_sql;
--EXECUTE stmt1;
Also, I haven't seen the use of an underscore (_) for variable assignment, perhaps that may also be playing a role in this?