Хранимая процедура mssql_execute ADODB / SQL Server не работает, но работает, если для debug установлено значение true
Я подключаюсь к базе данных 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
Я использую adodb 5.11
2 ответа
Когда вы устанавливаете 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();
}
}
Надеюсь, поможет!!
Хорошо, после нахождения комментариев php.net, хотя мои freetds не были настроены с правильным именем, я использовал IP-адрес. Я также не использовал V 8.0, я использовал 7.0, и до этого момента все работало нормально с процедурами хранения. Я попробовал решение mssql_free_result, предоставленное в комментариях и ответе DarkThrones, и это не сработало, но когда я использовал метод close(), он работает. Он использует бесплатный результат и передает идентификатор запроса.
Если кто-то может прокомментировать, почему это необходимо, это было бы здорово. Это потому, что я использовал слишком много памяти или что-то еще?