Trick to reset odbc_error()

Я узнал, что odbc_execute() не всегда вызывает правильную ошибку ODBC, когда возвращает FALSE (не по крайней мере с драйвером Oracle), и я не могу полностью доверять odbc_error() или odbc_errormsg(). Эта ситуация легко обнаружить, когда не было предыдущей ошибки, потому что odbc_error() возвращает пустую строку. Однако, когда он возвращает что-то, я не знаю, принадлежит ли это последней неудавшейся операции или она остается от предыдущей ошибки.

Простейшим решением было бы reset функции odbc_error() и odbc_errormsg() при возникновении ошибки, поэтому следующие вызовы начинались бы с нуля, но я не мог найти способ, который можно было бы поддерживать. Можете ли вы найти способ сделать это?

Фон: я улучшаю устаревшее приложение с классом, который инкапсулирует вызовы базы данных. Вот почему мне нужно сделать все как можно более общим.

Ответ 1

не требуется reset функция, которую я решил таким образом:

function foo($sql){
   $res = odbc_exec($this->dbconn, $sql);
   if (odbc_error () and $res===false ) {
       return $this->catchException(odbc_errormsg($this->dbconn));

   }
    return $res;
}

Ответ 2

odbc_error иногда становится запутанным. исполняемая строка sql и сообщение об ошибке могут отличаться. Чтобы этого избежать, мы можем сохранить все выполненные sqls в массиве, и после завершения выполнения мы можем проверить, что такое сообщения об ошибках.

Сначала давайте определим класс executeSQL, который будет содержать исполняемые данные sqls:

class executedSQL 
{
    public sql;
    public result;
    public error;
    public message;
}

Этот класс будет содержать всю информацию sql и их результат и возвращенные сообщения.

Если мы используем класс для подключения odbc db:

class myODBC
{
    //holds the connection
    public $connection;

    //all executed sql string are added to this array as executedSQL object.
    public $executedSQLs = array();


    public function connect()
    {
        $this->connection = dbc_connect(" ", " ","") or die(odbc_errormsg());
    }

    public function execute($sql)
    {
        $execution = odbc_exec($this->connection, $sql); //execute it

        //put all the results to executedSQL object
        $executed = new executedSQL();
        $executed->sql = $sql;
        $executed->result = $execution;
        $executed->error = odbc_error();
        $executed->message = odbc_errormsg();

        //push to executedSQLs var.
        array_push($this->executedSQLs, $executed);

        return $execution;
    }
}

Если мы выполним наши sqls:

$db = new myODBC();

$db->connect();

$db->execute("select * from table1");
$db->execute("this is gonna be failed sql");
$db->execute("select * from table2");

print_r($db->executedSQLs);

Это будет печатать все sqls и их результаты. На этом этапе мы можем увидеть выполненный sql и связанное с ним сообщение об ошибке. Так что буквально мы не сбрасываем odbc_error, но делаем это более понятным. Если сообщение об ошибке повторяется дважды, более вероятно, что оно принадлежит предыдущему исполненному sql. Таким образом, отладка становится проще.

Ответ 3

odbc_errormsg ошибки не могут быть reset во время script. Таким образом, на самом деле простой способ отделить odbc_errormsg-ошибки - назначить каждому obdc_connect уникальный идентификатор. Примеры показывают $db = @odbc_connect ($ somefile,......), но используя либо случайные, либо уникальные имена = > $db900 = @odbc_connect ($ somefile,......) или $myuniquename = @odbc_connect ( $somefile,......) будут разделять сообщения об ошибках. Затем использование odbc_errormsg ($ myuniquename) вернет ошибку только для этого id.