使用PDO/PHP从一个存储过程中获取两个不同的结果

使用PDO/PHP从一个存储过程中获取两个不同的结果,php,sql-server,symfony,pdo,doctrine-orm,Php,Sql Server,Symfony,Pdo,Doctrine Orm,使用SQL Server数据库构建Symfony 4 API时,我遇到了一个问题:我必须从一个存储过程中获取两个不同的结果 第一个结果是一个数据数组,第二个结果只是一个int值 我正在对后端分页进行编码,这就是为什么我需要获取数据,以及表中的行总数 以下是我的存储过程: ALTER PROCEDURE [SP IDENTIFIER] ( @Limit INT, @Offset INT ) AS BEGIN SET NOCOUNT O

使用SQL Server数据库构建Symfony 4 API时,我遇到了一个问题:我必须从一个存储过程中获取两个不同的结果

第一个结果是一个数据数组,第二个结果只是一个int值

我正在对后端分页进行编码,这就是为什么我需要获取数据,以及表中的行总数

以下是我的存储过程:

ALTER PROCEDURE [SP IDENTIFIER] 

    (
        @Limit INT,
        @Offset INT

    )
AS
BEGIN

    SET NOCOUNT ON; 

    SELECT 
        COUNT(*) AS 'TOTAL'
    FROM DataBaseName

SELECT Field1, Field2, Field3
FROM DataBaseName
ORDER BY Field1 DESC
OFFSET @Offset ROWS
FETCH NEXT @Limit ROW ONLY


END
当我测试API时,它只返回第一个请求的结果(行数值)

以下是如何使用我的存储库方法:

  public function getDatas($limit, $offset)
  {
    $request = "EXEC SPName ?, ?";
    $answer = $this->_em->getConnection()->prepare($request);
    $answer->bindParam(1, $limit);
    $answer->bindParam(2, $offset);
    $answer->execute(); 


    return $answer->fetchAll();
  }
你知道如何让PDO返回他从请求中得到的所有结果吗?可能是在fetch选项中,或者以某种方式在$answer中执行fetchAll循环


谢谢

必须为存储过程指定输出参数,并且客户端代码必须能够接受输出

我已经有几个月没有使用SQL Server了,但是我很确定我使用的版本不允许存储过程使用ALTER,而且我已经没有SQL Server了,所以我无法测试我将要交付给您的内容

此外,我认为您第一次“认为”该过程正在工作,但我猜该变量已经加载了有效值,因此似乎设置正确

请尝试以下操作并修改您的客户端代码以接受@myCount:

IF OBJECT_ID('SP IDENTIFIER', 'P') IS NOT NULL  
    DROP PROCEDURE [SP IDENTIFIER];  
GO  

CREATE PROCEDURE [SP IDENTIFIER]
          @Limit INT, @Offset INT, @myCount INT OUTPUT
AS
BEGIN

SET NOCOUNT ON; 

SELECT @myCount = COUNT(*)
FROM DataBaseName

SELECT Field1, Field2, Field3
FROM DataBaseName
ORDER BY Field1 DESC
OFFSET @Offset ROWS
FETCH NEXT @Limit ROW ONLY

END

您必须为存储过程指定输出参数,并且您的客户机代码必须能够接受输出

我已经有几个月没有使用SQL Server了,但是我很确定我使用的版本不允许存储过程使用ALTER,而且我已经没有SQL Server了,所以我无法测试我将要交付给您的内容

此外,我认为您第一次“认为”该过程正在工作,但我猜该变量已经加载了有效值,因此似乎设置正确

请尝试以下操作并修改您的客户端代码以接受@myCount:

IF OBJECT_ID('SP IDENTIFIER', 'P') IS NOT NULL  
    DROP PROCEDURE [SP IDENTIFIER];  
GO  

CREATE PROCEDURE [SP IDENTIFIER]
          @Limit INT, @Offset INT, @myCount INT OUTPUT
AS
BEGIN

SET NOCOUNT ON; 

SELECT @myCount = COUNT(*)
FROM DataBaseName

SELECT Field1, Field2, Field3
FROM DataBaseName
ORDER BY Field1 DESC
OFFSET @Offset ROWS
FETCH NEXT @Limit ROW ONLY

END

MS SQL Server支持可以返回多个结果集的存储过程。使用PHP和PDO,您可以使用方法检索这些结果集。重要的是要知道,即使存储过程中有输出参数,也需要获取所有结果集以获得输出值

您可以尝试以下方法:

public function getDatas($limit, $offset)
{
    $request = "EXEC SPName ?, ?";
    $answer = $this->_em->getConnection()->prepare($request);
    $answer->bindParam(1, $limit);
    $answer->bindParam(2, $offset);
    $answer->execute(); 

    do {
        // Fetch records with $answer->fetchAll();
    while ($answer->nextRowset());
}

MS SQL Server支持可以返回多个结果集的存储过程。使用PHP和PDO,您可以使用方法检索这些结果集。重要的是要知道,即使存储过程中有输出参数,也需要获取所有结果集以获得输出值

您可以尝试以下方法:

public function getDatas($limit, $offset)
{
    $request = "EXEC SPName ?, ?";
    $answer = $this->_em->getConnection()->prepare($request);
    $answer->bindParam(1, $limit);
    $answer->bindParam(2, $offset);
    $answer->execute(); 

    do {
        // Fetch records with $answer->fetchAll();
    while ($answer->nextRowset());
}

我终于解决了我的问题

您必须使用nextRowSet()方法。你可以用条令在你的陈述对象上调用它,但不能再用条令2了。 因此,首先必须通过在getConnection()之后调用getWrappedConnection()方法来获取真正的PDO对象

在此之后,您只需循环数据并将其堆叠到数组或对象中

以下是我的解决方案:

  public function getPaginedSubscriptions($limit, $offset)
  {
    $sql = "EXEC DB_EXTRANET_V2.dbo.P_S_ORDER_00 ?, ?";
    $request = $this->_em->getConnection()->getWrappedConnection()->prepare($sql);
    $request->bindParam(1, $limit);
    $request->bindParam(2, $offset);
    $request->execute();

    do{
      $datas[] = $request->fetchAll();
    } while($request->nextRowSet());

    return $datas;
  }

我终于解决了我的问题

您必须使用nextRowSet()方法。你可以用条令在你的陈述对象上调用它,但不能再用条令2了。 因此,首先必须通过在getConnection()之后调用getWrappedConnection()方法来获取真正的PDO对象

在此之后,您只需循环数据并将其堆叠到数组或对象中

以下是我的解决方案:

  public function getPaginedSubscriptions($limit, $offset)
  {
    $sql = "EXEC DB_EXTRANET_V2.dbo.P_S_ORDER_00 ?, ?";
    $request = $this->_em->getConnection()->getWrappedConnection()->prepare($sql);
    $request->bindParam(1, $limit);
    $request->bindParam(2, $offset);
    $request->execute();

    do{
      $datas[] = $request->fetchAll();
    } while($request->nextRowSet());

    return $datas;
  }

谢谢你的回答,我觉得很有趣!我不明白为什么,但这还不起作用,就像条令不知道nextRowset()方法一样。试图调用类“条令\DBAL\Statement”的未定义方法“nextRowset”。$answer似乎不是真正的PDO实例!谢谢你的回答,我觉得很有趣!我不明白为什么,但这还不起作用,就像条令不知道nextRowset()方法一样。试图调用类“条令\DBAL\Statement”的未定义方法“nextRowset”。$answer似乎不是真正的PDO实例!