Извлечение 2 разных результатов из одной хранимой процедуры с помощью PDO / PHP - PullRequest
0 голосов
/ 06 декабря 2018

При создании API Symfony 4 с базой данных SQL Server я столкнулся с проблемой: мне нужно извлечь два разных результата из одной хранимой процедуры.

Первый результат - это массив данных, асекунда - это просто значение типа 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 возвращать все результаты, полученные им по запросу?Может быть, в варианте выборки или каким-то образом делать цикл fetchAll в $ answer?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

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());
}
0 голосов
/ 07 декабря 2018

Я наконец-то решил свою проблему.

Вы должны использовать метод nextRowSet ().Вы можете вызывать его в своем объекте оператора с помощью Doctrine, но больше не с Doctrine 2. Итак, сначала вы должны получить истинный объект PDO, вызвав метод getWrappedConnection () после getConnection ().

После этого,вам просто нужно будет зациклить данные и сложить их в массив или объект.

Вот мое решение:

  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;
  }
0 голосов
/ 06 декабря 2018

Вы должны указать параметры 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
...