使用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循环?
谢谢!
MS SQL Server支持可以返回多个结果集的存储过程。使用PHP和PDO,您可以使用PDOStatement::nextRowset((方法检索这些结果集。重要的是要知道,即使存储过程中有输出参数,也需要获取所有结果集才能获得输出值。
你可以试试这个:
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());
}
您必须为存储过程指定OUTPUT参数,并且您的客户端代码必须能够接受输出。
我使用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
我终于解决了我的问题。
您必须使用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;
}