prepare语句将逗号分隔的值传递到存储过程参数
我无法将查询移入商店程序。我需要为两个 IN
子句传递一个以逗号分隔的字符串到参数 yr_model_no
我已经读了几个线程,并决定使用prepare语句。原始查询工作得很好,获取多行,但在存储过程中,当我用调用load_things('1283943kd9,2e9kk389334','53')
一个模型号列表,第二个是用户id),它只能从逗号分隔字符串的第一个值获取一个单一行。起初,我认为这是 yr_model_no
参数的长度问题,但将其更改为 varchar(200)
在where clause错误中给我未知列 2e9kk389334
。有人可以帮助我弄清楚在下面的代码中的prepare语句或参数有什么问题?
I have trouble moving a query into a store procedure. I need to pass a comma-separated string to the parameter yr_model_no
for two IN
clauses. I have read a few threads and decided to use prepare statements. The original query works fine fetching multiple rows, but in the stored procedure, when I call it with call load_things('1283943kd9,2e9kk389334','53')
(the first is a list of model numbers and the second is an user id), it can only fetch one single row from the first value of the comma-separate string. At first, I thought it was the length problem with the yr_model_no
parameter, but changing it to varchar(200)
would give me unknown column 2e9kk389334
in 'where clause' error. Can someone help me figure out what is wrong with the prepare statement or parameters in the following code?
以下是类似的小提示示例我的表模式和查询。
Here's a similar fiddle example of my table schema and query.
DELIMITER ;;
CREATE PROCEDURE `load_things` (IN `yr_model_no` varchar(20), IN `yr_app_id` int(5))
BEGIN
SET @s =
CONCAT('
SELECT * FROM
(
SELECT COUNT( c.app_id ) AS users_no, ROUND( AVG( c.min ) , 1 ) AS avg_min, ROUND( AVG( c.max ) , 1 ) AS avg_max, a.mid, a.likes, a.dislikes, b.model_no
FROM `like` a
RIGHT JOIN `model` b ON a.mid = b.mid
LEFT JOIN `details` c ON c.mid = b.mid
WHERE b.model_no IN (',yr_model_no,')
GROUP BY b.model_no
)TAB1
JOIN
(
SELECT a.app_id,b.model_no,IFNULL(c.isbooked,0) AS isbooked,d.min,d.max,e.like_type
FROM `users` a
JOIN `model` b
ON b.model_no IN (',yr_model_no,')
LEFT JOIN `favorite` c
ON c.app_id = a.id
AND c.mid = b.mid
LEFT JOIN `details` d
ON d.app_id = a.id
AND d.mid = b.mid
LEFT JOIN `users_likes` e
ON e.app_id = a.id
AND e.mid = b.mid
WHERE a.id = ',yr_app_id,'
)TAB2
ON TAB1.model_no = TAB2.model_no');
PREPARE stmt from @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt3;
END;;
DELIMITER ;
如果你想到你的语句生成的SQL它将看起来像这样
If you think about the SQL that your statement is generating it will look like this
JOIN `model` b
ON b.model_no IN (1283943kd9,2e9kk389334)
这是无效的SQL(需要引用varchar值)
This is invalid SQL (you need quotes around the varchar values)
您需要确保在传递给过程的字符串中的每个值附加引号:
You need to make sure you add quotes around each value in the string that you pass to your procedure:
load_things('''1283943kd9'',''2e9kk389334''','53')
不确保这是正确的方式来转义字符串在MySQL(你可能需要看看文档)
Not sure if this is the correct way to escape strings in MySQL (you might need to look at the docs)
这将导致:
JOIN `model` b
ON b.model_no IN ('1283943kd9','2e9kk389334')