存储过程的php PDO结果为空

Posted

技术标签:

【中文标题】存储过程的php PDO结果为空【英文标题】:php PDO result from stored procedure are empty 【发布时间】:2018-06-05 11:13:24 【问题描述】:

这里有一个例子:

SQL:

CREATE PROCEDURE my_sp(
  IN in_var VARCHAR(32)
)
BEGIN

     -- This is to avoiding the next problem:
     -- If I USE bellow: EXECUTE USING in_var NOT WORK
     -- But IF I USE: EXECUTE USING @user_invar WORKING GOOD
     SET @user_invar = in_var;

    SET @query = "SELECT * FROM my_table  WHERE my_column = ? LIMIT 1;";

    PREPARE stmt FROM @query;
    EXECUTE stmt USING @user_invar;
     SET @founded_rows = FOUND_ROWS();
    DEALLOCATE PREPARE stmt;

    IF(@founded_rows = 0)THEN
        SELECT 'ZERO_REZULTS' AS RESULTS;
    END IF;  
END;

php

$dbh = new PDO( $connection_params );

$sql = "CALL my_sp( :in_var )";
$stmt = $dbh->prepare( $sql );
$stmt->execute( array( ':in_var' => $_POST['in_var'] ) );
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

//No errors but $rows is an empty array if @founded_rows is 0
//espected RESULTS = ZERO_REZULTS

奇怪的是,如果我从 phpmyadmin 界面执行过程 my_sp() ,则该过程会按预期工作。我得到了:

RESULTS = ZERO_REZULTS

已编辑:

除了@Bill Karwin 的回答之外,要按预期工作,该过程必须在 stmt 中具有最后一个 SELECT,如下所示:

CREATE PROCEDURE my_sp(
  IN in_var VARCHAR(32)
)
BEGIN

SET @user_invar = in_var;

SET @query = "SELECT * FROM my_table  WHERE my_column = ? LIMIT 1;";

PREPARE stmt FROM @query;
EXECUTE stmt USING @user_invar;
SET @founded_rows = FOUND_ROWS();
IF(@founded_rows = 0)THEN
    SELECT 'ZERO_REZULTS' AS RESULTS;
END IF;  
DEALLOCATE PREPARE stmt;

结束;

【问题讨论】:

错误报告和 pdo 错误处理的任何内容? @FunkFortyNiner 没有错误 php 中的结果是好的,但是数组是空的。 我怀疑问题在于该过程返回的列数取决于第一个 SELECT 是否返回某些内容。 尝试更改IF,使其返回与第一个查询相同的列数。 @Barmar 所以你建议使用NULL AS real_fields .... 'NO_RESULT' AS RESULT ? 【参考方案1】:

查询需要相同数量的列的建议不是问题。存储过程生成多个不同的结果集,而不是 UNION。

第一个 SELECT 生成零行的结果集。您仍然必须fetchAll() 才能使用此行集,即使它是“空的”。然后你必须使用nextRowset() 前进到proc 返回的下一个行集。

$dbh = new PDO( $connection_params );

$sql = "CALL my_sp( :in_var )";
$stmt = $dbh->prepare( $sql );
$stmt->execute( array( ':in_var' => $_POST['in_var'] ) );

do 
    $rowset = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if ($rowset) 
        ...do something with rowset...
    
 while ($stmt->nextRowset());

另请参阅:http://php.net/manual/en/pdostatement.nextrowset.php

【讨论】:

有道理。 是的,这就是答案,但只有一点点观察:要工作,mi 示例中的最后一个SELECT 必须在 stmt 内部而不是之后。如果在之后(就像在 mi 原始问题中一样),结果仍然是空的,但是如果我把它们放在 stmt 中(就在DEALLOCATE PREPARE stmt; 之前,那工作得很好

以上是关于存储过程的php PDO结果为空的主要内容,如果未能解决你的问题,请参考以下文章

PHP PDO:存储过程返回空结果

php pdo调用SQLServer存储过程无法获取返回结果

无法使用 PHP PDO 获取 SQL Server 打印消息

从 MS SQL 中的 PHP PDO 存储过程中返回 Select *

在 PHP 中使用 PDO 创建存储过程

PHP MySQL PDO 存储过程和 INOUT 参数