php PDO :: FETCH_ASSOC не определяет выбор после резервного копирования в хранимой процедуре - PullRequest
3 голосов
/ 03 июня 2019

У меня есть хранимая процедура, которая делает резервную копию, а затем возвращает 1 или 0, если есть ошибка или нет что-то вроде этого:

Create procedure [dbo].[sp_IWBackup]
as
begin
declare @route varchar(500),  @answer int = 0
set nocount on
set @route = 'I:\route'+(replace((replace(convert(varchar, getdate(), 21),':',';')),'.',';'))+'Full.bak'
set @answer = 1
begin try
backup database databasename to disk = @route
end try
begin catch
set @answer = 0
end catch
select @answer as answer
end

В sql это работает и возвращает правильное значение @ answer.

В php, когда я пытаюсь получить выполнение запроса, он ничего не находит.

public function ExecuteSelectAssoc($sth)
    {
        $r=array('data'=>false,
        'error'=>false,
        'r'=>array());
        try {
            $sth->execute();
            while ($row=$sth->fetch(PDO::FETCH_ASSOC)) {  //error here
                $r['data'] = true;
                $keys = array_keys($row);
                $tmp = array();
                foreach($keys as $key)
                {
                    $tmp[$key] = $row[$key];
                }
                array_push($r['r'], $tmp);
            }
        } catch (PDOException $e) {
            $r['error']=true;
            $r['r'] = $e->getMessage();
        }
        return $r;
    }

Атрибуты PDO

public function connectSqlSrv(){
        try{
            $dbCnx = new PDO("sqlsrv:Server=$this->server;Database=$this->db", $this->usr, $this->psw);
            $dbCnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $dbCnx;
        }
        catch(PDOException $e){
            echo $e;
            die();
            return null;
        }
    }

И я получаю эту ошибку:

r: "SQLSTATE [IMSSP]: активный результат для запроса не содержит полей."

И я ожидаю: Ответ: 1

1 Ответ

1 голос
/ 04 июня 2019

Пояснения:

Причина вашей ошибки в том, что BACKUP DATABASE возвращает информационные сообщения, а ваша хранимая процедура имеет несколько наборов результатов.Я воспроизвел вашу ошибку с помощью тестового сценария (хотя в вашем вопросе я не вижу, как вы готовите хранимую процедуру).Вы можете попробовать одно из следующих решений (я создал простые сценарии, которые вы можете легко реализовать в своих функциях).

  • вызов PDOStatement :: nextRowset чтобы получить каждый набор результатов (в данном случае два дополнительных вызова)

  • используйте параметр OUTPUT в вашей хранимой процедуре.В этом случае вам нужно получить все наборы результатов, а затем получить значение выходного параметра.

Решение 1:

Сохраненопроцедура:

create procedure [dbo].[sp_IWBackup]
as
begin
    declare 
       @route varchar(500),  
       @answer int = 0
    set nocount on

    set @route = 'I:\route'+(replace((replace(convert(varchar, getdate(), 21),':',';')),'.',';'))+'Full.bak'
    set @answer = 1

    begin try
        backup database databasename to disk = @route
    end try
    begin catch
        set @answer = 0
    end catch

    select @answer as answer
end

PHP:

<?php
$server   = 'server\instance,port';
$database = 'database';
$uid      = 'uid';
$pwd      = 'pww';

try {
    $dbh = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
    die("Error connecting to SQL Server. ".$e->getMessage());
}

try {
    $sql = "{CALL sp_IWBackup}";
    $stmt = $dbh->prepare($sql);
    $stmt->execute();
    $stmt->nextRowset();
    $stmt->nextRowset();
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        foreach ($row as $key => $value) {
            echo $key.": ".$value."<br>";
        };
    }
} catch( PDOException $e ) {
    die( "Error executing stored procedure: ".$e->getMessage());
}
$stmt = null;

$dbh = null;
?>

Решение 2:

Хранимая процедура:

create procedure [dbo].[sp_IWBackupOut]
    @answer int OUTPUT
as
begin
    declare 
        @route varchar(500)
    set nocount on

    set @route = 'I:\route'+(replace((replace(convert(varchar, getdate(), 21),':',';')),'.',';'))+'Full.bak'
    set @answer = 1

    begin try
        backup database databasename to disk = @route
    end try
    begin catch
        set @answer = 0
    end catch
end

PHP:

<?php
$server   = 'server\instance,port';
$database = 'database';
$uid      = 'uid';
$pwd      = 'pww';

try {
    $dbh = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
    die("Error connecting to SQL Server. ".$e->getMessage());
}

try {
    $sql = "{CALL sp_IWBackupOut (?)}";
    $stmt = $dbh->prepare($sql);
    $answer = -1;
    $stmt->bindParam(1, $answer, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
    $stmt->execute();
    do {
    } while ($stmt->nextRowset());
    echo "answer: ".$answer;
} catch( PDOException $e ) {
    die( "Error executing stored procedure: ".$e->getMessage());
}
$stmt = null;

$dbh = null;
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...