Я пытаюсь выяснить, какие «части» оператора «RAISE EXCEPTION» отображаются в «части» PDOException. Может ли кто-нибудь объяснить «кто» и «как» выполнить это преобразование (или, еще лучше, указать на документ, который описывает этот или исходный код, который выполняет это)?
В частности, я хотел бы знать, есть ли способ повлиять на значение SQLSTATUS (в моих тестах всегда есть значение «P0001») и / или «ОШИБКА:» (которое является частью сообщения и всегда пустое)
Лучше всего мне удалось:
ИСКЛЮЧЕНИЕ ПОДЪЕМА ИСПОЛЬЗОВАНИЕ message = '<a message>', ERRCODE = 'UE001'
который на стороне PHP дает мне сообщение вроде:
ОШИБКА: NUM: UE001, DETAILS: <a message>
Но я не очень доволен этим. Было бы замечательно иметь возможность «поместить» UE001 в один из полей PDOException (поэтому мне не нужно разбирать его из строки сообщения).
Вы будете высоко оценены.
Используйте свойство code
PDOException
для получения SQLSTATE
. См. Документацию по PDOException
Чтобы управлять SQLSTATE
сгенерированным функцией PL / PgSQL, вызывающей ошибку, вы используете RAISE ... SQLSTATE
в соответствии с документацией .
Конечно, для этого для работы драйвер базы данных должен правильно сообщать SQLSTATE
. Я проверил, что PDO делает это, по крайней мере, в PHP 5.4.11 с PostgreSQL 9.2, на следующий отдельный примерный код, который может быть выполнен с исполняемым файлом командной строки php
:
<?php $pdo = new PDO('pgsql:'); $sql = <<<EOD CREATE OR REPLACE FUNCTION exceptiondemo() RETURNS void AS $$ BEGIN RAISE SQLSTATE 'UE001' USING MESSAGE = 'error message'; END; $$ LANGUAGE plpgsql EOD; $sth = $pdo->prepare($sql); if (!$sth->execute()) { die("Failed to create test function\n"); } $sql = "SELECT exceptiondemo();"; $sth = $pdo->prepare($sql); if (!$sth->execute()) { $ei = $sth->errorInfo(); die("Function call failed with SQLSTATE " . $ei[0] . ", message " . $ei[2] . "\n"); // Shortcut way: // die("Function call failed with SQLSTATE " . $sth->errorCode()); } ?>
Выход:
Function call failed with SQLSTATE UE001, message ERROR: error message
Замените блок кода со второго $sth->execute()
до конца кода этим, чтобы продемонстрировать, что режим обработки исключений также работает отлично:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); try { $sth->execute(); } catch (PDOException $err) { $ei = $err->errorInfo; die("Function call failed with SQLSTATE " . $ei[0] . ", message " . $ei[2] . "\n"); // Alternate version to just get code: //die("Function call failed with SQLSTATE " . $err->getCode() . "\n"); }