我正在将所有mysqli查询迁移到STORED PROCEDURE。 它应该像更改mysqli调用中的一行一样简单,但是,以下两个代码会给出不同的结果:
常规查询,它可以正常工作:
$query = $this->mysqli->query("SELECT DISTINCT ID FROM user
WHERE
MATCH (name) AGAINST ('* *$sanitized* *') ");
if ($query) {
$nrows = $query -> num_rows;
if ($nrows > 0) {
$searchResult = 'We found '. $nrows .' results';
}
}
调用PROCEDURE,在布尔值"上返回" fetch_array()错误:
$query = $this->mysqli->query("CALL myfunction('.$sanitized.')");
程序定义为:
DELIMITER $$
CREATE PROCEDURE myfunction (sanitized VARCHAR(124))
BEGIN
SELECT DISTINCT ID FROM user
WHERE
MATCH (name) AGAINST ('* *sanitized* *');
END
$$
DELIMITER ;
我无法找到解决方案,似乎没有人在此论坛中遇到类似的问题。
答案 0 :(得分:0)
考虑与Prepared Statements一起使用concat()
,因为它们经常出现。
DROP PROCEDURE if exists myStoredProc101;
DELIMITER $$
CREATE PROCEDURE myStoredProc101
( pSanitized VARCHAR(124)
)
BEGIN
set @mySql:=concat("SELECT DISTINCT ID FROM user where match(name) against ('* *",pSanitized,"* *')");
PREPARE stmt1 FROM @mySql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END
$$
DELIMITER ;
你的存储过程没有机会工作,因为它甚至没有使用你的参数。你所做的是把一些东西埋在一个字符串文字中。另外,varchar(124)有点奇怪:p
关于人们对预备语句的唯一成功是使用用户变量(使用@
)与使用本地变量(来自DECLARE)失败的尝试。所以,这可能会为你节省几个小时的头部撞击。
从PHP手册页Stored Procedures:
处理结果集
存储过程可以返回结果集。从a返回的结果集 使用mysqli_query无法正确获取存储过程。该 mysqli_query函数结合了语句执行和获取 第一个结果集设置为缓冲结果集(如果有)。但是,那里 是对用户隐藏的附加存储过程结果集 导致mysqli_query无法返回用户预期的结果集。
使用提取从存储过程返回的结果集 mysqli_real_query或mysqli_multi_query。这两个功能都允许抓取 语句返回的任意数量的结果集,例如CALL。 无法获取存储过程返回的所有结果集会导致 错误。
至于从mysqli
调用存储过程,请查看来自Pablo Tobar的Answer。对于许多变量来说,它看起来并不特别令人愉快,但这似乎就是它所处的位置。 Spoiler Alert:使用mysql变量,而不是PHP变量。
当然,Pablo没有返回结果集,而是写入存储过程中的OUT
var。也许你需要做他为IN
参数做的事情,然后调用multi_query()
,然后调用store_result()
,然后调用fetch_all()
(简而言之,PHP引用页面向上) )。
或者,可以通过Palladium here进行电话会议。
在任何一种情况下,都必须采取措施避免将 SQL注入传递给存储过程例程的已知漏洞。