MySQL(存储)过程 - 参数和查询
Posted
技术标签:
【中文标题】MySQL(存储)过程 - 参数和查询【英文标题】:MySQL (Stored) Procedure - parameters and query 【发布时间】:2013-10-10 12:19:20 【问题描述】:我正在尝试创建一个带参数的简单过程。
CALL new_procedure('mode', 'ASC');
第一个输入是列,第二个是排序方向
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`(IN in_order_by_column varchar(20), in_order_by_direction char(4))
BEGIN
DECLARE order_by varchar(30);
SET @order_by = CONCAT('`', in_order_by_column, '` ', in_order_by_direction);
/*
SELECT * FROM `common_tags` ORDER BY @order_by LIMIT 5;
*/
SELECT @order_by as 'c';
END
在上面的例子中,我只输出了 2 个参数,所以我可以看到发生了什么。
结果:
"c"
`mode` ASC
.
当我使用预期代码运行该过程时,如下所示。
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`(IN in_order_by_column varchar(20), in_order_by_direction char(4))
BEGIN
DECLARE order_by varchar(30);
SET @order_by = CONCAT('`', in_order_by_column, '` ', in_order_by_direction);
SELECT * FROM `common_tags` ORDER BY @order_by LIMIT 5;
END
结果
tags_id data mode parent_id position
1 Wood 2 13 6
2 Trippy 0 0 0
4 Artists 1 0 1
6 "Newest Additions" 1 0 11
12 "Natural Elements" 2 5 8
如您所见,结果未按mode
排序。
感谢任何帮助。
【问题讨论】:
【参考方案1】:很遗憾,在这种情况下,您需要PREPARE
整个查询:
DELIMITER $$
DROP PROCEDURE IF EXISTS `new_procedure`$$
CREATE PROCEDURE `new_procedure`(IN in_order_by_column varchar(20), in_order_by_direction char(4))
BEGIN
SET @buffer = CONCAT_WS('',
'SELECT * FROM `common_tags` ORDER BY `', in_order_by_column, '` ', in_order_by_direction, ' LIMIT 5'
);
PREPARE stmt FROM @buffer;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
注意:应非常小心使用所描述的方法,因为如果使用不当,很容易受到 SQL 注入攻击。
【讨论】:
您可能希望使用quote()
引用输入值,请参阅dev.mysql.com/doc/refman/8.0/en/…
@Leukipp OP 正在尝试使用不同的列和方向来构建查询。您建议的函数旨在转义值,而不是用于列、方向或任何查询描述部分。
我的评论提到了您关于构造查询易受 SQL 注入攻击的注释。
澄清@Leukipp的建议:这个特定的构造查询只使用参数作为列名和SQL关键字 - 使用quote()
会导致错误。就像 BlitZ 一样,通过用反引号包围列名来保护列名不被注入。 Leukipp 的评论对于将这种技术用于查询中作为 values 的参数的任何人来说确实很有用(因此在不同的 concat'd 查询中对我很有用,以避免 SQL 注入)。
关于 SQL 注入的更多信息:in_order_by_direction
不受保护;更好的方法是传入一个经过测试的布尔值,在 CONCAT 查询时替换为 ASC
或 DESC
。为了安全起见,查询的每个部分都必须通过某种方式加以保护。以上是关于MySQL(存储)过程 - 参数和查询的主要内容,如果未能解决你的问题,请参考以下文章