Как подавить произвольные предупреждения / сообщения об ошибках от DBI? - PullRequest
3 голосов
/ 23 февраля 2012

код:

# A:
$dbh->do(qq/insert into foo(cl) values('test')/);
# B:
$dbh->do(qq/insert into foo(cl) values('test')/) or warn $dbh->errstr;
# C:
eval { $dbh->do(qq/insert into foo(cl) values('test')/); };
warn "error : $@ " if $@;

Все будут выводить:

DBD::mysql::db do failed: Duplicate entry 'test' for key 'cl' at a.pl line 9.

Я не хочу, чтобы это произвольное предупреждение / сообщение об ошибке отправлялось на stderr. Я хотел бы использовать warn $dbh->errstr.

perl a.pl 2>/dev/null подавит сообщение об ошибке, но я хочу знать, как это сделать в сценарии?

Ответы [ 2 ]

8 голосов
/ 23 февраля 2012

Вам необходимо установить собственный обработчик ошибок.Например,

$dbh->do($statement, { HandleError => \&handle_error });

Обработчики ошибок описаны в DBI POD

Другие варианты:

  • Установить PrintWarnатрибут false значение (любезно предоставлено ответом Синан на каком-либо форуме

  • Перехватывать все предупреждения через обработчик сигнала: $SIG{'__WARN__'} = sub {};

2 голосов
/ 23 февраля 2012

В настоящее время я обычно делаю следующее

  1. Всегда передайте RaiseError => 1, PrintError => 0 при создании дескриптора DBI. Теперь вам не нужно добавлять обработчик ошибок к каждому вызову DBI.
  2. Для заявлений, в которых меня не волнуют ошибки дублирующегося ключа, перехватите и игнорируйте это исключение:

    use Try::Tiny;
    try { $dbh->do(...) }
    catch { die $_ unless /execute failed: Duplicate entry/ };
    

Это лучший способ, который я нашел - INSERT IGNORE игнорирует все ошибки, а не только ошибки дублирующихся ключей, и REPLACE перезапишет существующую строку, используя удаление и вставку. INSERT INTO ... ON DUPLICATE KEY UPDATE id=id, возможно, может использоваться, но я думаю, что отлов ошибки более явный.

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