Хранимая процедура mssql_execute ADODB / SQL Server не работает, но работает, если для debug установлено значение true - PullRequest
0 голосов
/ 16 января 2011

Я подключаюсь к базе данных SQL Server из PHP, используя ADODB. У меня есть несколько хранимых процедур, которые я выполняю просто отлично. Последний звонок, который я по какой-то причине создал, продолжает сбой. Я поставил отладку как правда, и она работает просто отлично. Я понятия не имею, почему это будет происходить.

вот ошибка, которую я получаю

Error: mssql_execute() [<a href='function.mssql-execute'>function.mssql-execute</a>]:      stored procedure execution failed  in /path/to/adodb/lib/adodb5/drivers/adodb-mssql.inc.php on line 768

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

protected function _getSpArray($db, $sp, array $spParams) {
    try {
        $stmt = $db->PrepareSP($sp);
        foreach ($spParams as $param) {
            $db->InParameter($stmt, $param[0], $param[1]);
        }
        $db->SetFetchMode(ADODB_FETCH_ASSOC);
        $rs = $db->Execute($stmt);
        $rsArray = array();
        if (!$rs) {
            echo 'No records found \n';
            return;
        }
        else {
            foreach ($rs as $k => $row) {
                $rsArray[$k] = $row;
            }
        }
        return $rsArray;
    } catch (ErrorException $e) {
        echo $e->getMessage();
    }
}

Ошибка в этой строке # 768 adodb5 / drivers / adodb-mssql.inc.php

$rez = mssql_execute($sql[1]);

и массив sql имеет эти значения

[0] stored_procedure_name
[1] resource id='657' type='mssql statement'

Я видел следующие комментарии на PHP.net, я изменил имя своего хоста freetds на другое, отличное от IP-адреса, и все еще ничего. Я не уверен в бесплатном результате, так как я использую adodb.

http://www.php.net/manual/en/function.mssql-execute.php#93938

Я использую Adodb 5.11

Ответы [ 2 ]

2 голосов
/ 16 января 2011

Когда вы устанавливаете debug как true, ADODB использует другую функцию для выполнения оператора.В этом случае function _adodb_debug_execute(&$zthis, $sql, $inputarr)

Если для debug установлено значение false, ADODB использует function &_Execute($sql,$inputarr=false).Когда вы проверяете источник для обоих методов, вы можете ясно увидеть разницу.

<?php
function _adodb_debug_execute(&$zthis, $sql, $inputarr)
{
    //ADODB prepares debug information dump...

    $qID = $zthis->_query($sql,$inputarr);

    //Here ADODB makes the difference

    if ($zthis->databaseType == 'mssql') { 
    // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
        if($emsg = $zthis->ErrorMsg()) {
            if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
        }
    } else if (!$qID) {
        ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
    }

    if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
    return $qID;
}
?>

Вот функция _Execute

<?php
function &_Execute($sql,$inputarr=false){
        //Here ADODB chooses which fn to use
        if ($this->debug) {
            global $ADODB_INCLUDED_LIB;
            if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
            $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr);
        } else {
            $this->_queryID = @$this->_query($sql,$inputarr);
        }
        //...

        if ($this->_queryID === false) { // error handling if query fails
            //If debug ADODB prints backtrace regardless the result
            if ($this->debug == 99) adodb_backtrace(true,5);    
            $fn = $this->raiseErrorFn;
            if ($fn) {
                $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this);
            } 
            $false = false;
            //Returns false no matter what...
            return $false;
        } 
        //...
    }
?>

Попробуйте добавить это в ваш скрипт, чтобы проверить поведение скрипта и иметь в виду, что в случае сбоя выполнения он вернет false значение.Так что позаботьтесь с возвращаемым значением.

protected function _getSpArray($db, $sp, array $spParams) {
    try {
        $stmt = $db->PrepareSP($sp);
        foreach ($spParams as $param) {
            $db->InParameter($stmt, $param[0], $param[1]);
        }
        $db->SetFetchMode(ADODB_FETCH_ASSOC);
        $rs = $db->Execute($stmt);
        $rsArray = array();
        if (!$rs) {
            echo 'No records found \n';
            return;
        }
        else {
            foreach ($rs as $k => $row) {
                $rsArray[$k] = $row;
            }
        }
        //add this line to free the resources after use. 
        mssql_free_result($rs);
        return $rsArray;
    } catch (ErrorException $e) {
        echo $e->getMessage();
    }
}

Надеюсь, это поможет !!

0 голосов
/ 17 января 2011

Хорошо, после нахождения комментариев php.net, хотя мои freetds не были настроены с правильным именем, я использовал IP-адрес.Я также не использовал V 8.0, я использовал 7.0, и до этого момента все работало нормально с процедурами хранения.Я попробовал решение mssql_free_result, предоставленное в комментариях и ответе DarkThrones, и это не сработало, но когда я использовал метод close (), он работает.Он использует бесплатный результат и передает идентификатор запроса.

Если кто-то может прокомментировать, почему это необходимо, это было бы здорово.Это потому, что я использовал слишком много памяти или что-то в этом роде?

...