php - 使用存储过程 : different results in mysqli->query ("CALL select_procedure") VS mysqli->query ("SELECT ...")

标签 php mysql stored-procedures mysqli

我正在将所有 mysqli 查询迁移到存储过程。 它应该像更改 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() on boolean”错误:

$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 ;

我找不到解决方案,而且这个论坛上似乎没有人有类似的问题。

最佳答案

考虑 Prepared Statementsconcat() 一起使用和往常一样。

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 :

Handling result sets

Stored procedures can return result sets. Result sets returned from a stored procedure cannot be fetched correctly using mysqli_query. The mysqli_query function combines statement execution and fetching the first result set into a buffered result set, if any. However, there are additional stored procedure result sets hidden from the user which cause mysqli_query to fail returning the user expected result sets.

Result sets returned from a stored procedure are fetched using mysqli_real_query or mysqli_multi_query. Both functions allow fetching any number of result sets returned by a statement, such as CALL. Failing to fetch all result sets returned by a stored procedure causes an error.

关于从mysqli调用存储过程,请看Answer来自巴勃罗·托巴尔。对于许多变量,它看起来并不是特别令人愉快,但这似乎就是它所在的位置。剧透警告:使用 mysql 变量,而不是 PHP 变量。

当然,Pablo 没有返回结果集,而是写入存储过程中的 OUT var。也许你需要做他为 IN 参数做的事情,然后调用 multi_query(),然后是 store_result(),然后是 fetch_all()(简而言之,PHP 引用一个页面)。

或者,调用将由 Palladium 完成 here .

无论哪种情况,都必须注意大小写以避免将 SQL 注入(inject) 传递给存储过程例程的已知漏洞。

关于php - 使用存储过程 : different results in mysqli->query ("CALL select_procedure") VS mysqli->query ("SELECT ..."),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38294813/

相关文章:

php - '使用多个复选框搜索数据库'

php - 分解并为每个值创建数组

mysql - SQL 中的嵌套 IF 语句

PHP登录表单需要提交2次

php - 使用多文件 uploader 只上传一个文件

php - Yii Bootster - TbTabs 更改选项卡事件

php - AJAX更新删除表: backend works but glitch with frontend中的tr

mysql - mysql中的存储过程嵌套游标循环未执行所有结果

MySQL存储过程不起作用

sql - 存储过程(删除发票)