Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Подскажите как подавить вывод ошибки


Автор: vax1700 20.3.2006, 18:54
У меня есть таблица с полем 'word', на котором стоит UNIQUE индекс.
При работе скрипта я вставляю в таблицу слова. При дублировании слова мне нужно засечь факт дублирования.

Это я реализовал так:
Код
$dbh->do("INSERT INTO ... VALUES ....", { PrintError => 0, RaiseError => 0 } );

if ( $dbh->errstr() )
{
...
}

но при вставке одинакового слова вылетает фатальная ошибка (см. вложение)
Скажите как её подавить?

P.S. INSERT IGNORE делать не могу, т.к. не засеку факт дублирования.
Как видите выше пробовал применит %attr ( и в do и в connect), но не получается.
Кто сталкивался с подобной проблемой?

Автор: BlackLFL 20.3.2006, 19:09
Код

my $rv = $dbh->do("...");
unless ( $rv ) {
    print DBI->errstr;
}

Автор: vax1700 20.3.2006, 20:21
так у меня exception вылетает на $dbh->do!
и дальше не продолжает. Обрывает.

Автор: BlackLFL 20.3.2006, 20:55
значит у Вас где-то стоит перехватчик ошибок, например, если ошибка выводится на
экран, это может происходить из-за подключенного модуля CGI::Carp:
Код

use CGI::Carp qw(fatalsToBrowser);

Автор: vax1700 20.3.2006, 23:20
BlackLFL, Нет, ничего нет
ок, спасибо, может ещё кто-нибудь подскажет?
Я так думаю, что в $dbh->do надо какой-то специальный флаг передавать, чтобы мускуловские ошибки не были фатальными для $dbh->do.

Автор: igorold 21.3.2006, 07:16
А если до добавления слова делать запрос на проверку, что это слово уже есть в базе?
Код

SELECT word FROM table WHERE word='value'

если запрос окажется пустой, до делать insert

Автор: Ivan Kolesnikov 21.3.2006, 10:09
По моему, ты не в том месте используешь PrintError, по крайней мере у меня с Oracle твой пример тоже выдает сообщение на консоль.
Попробуй вот так:
Код

use DBI;
use strict;
my $dbh = DBI->connect($connect, $user, $password, {PrintError => 0});
$dbh->do("insert into ...") or print "Can not insert\n";

Автор: sharq 21.3.2006, 12:27
smile читаем внимательно perldoc DBI.


vax1700,
Цитата(vax1700 @ 20.3.2006, 19:54 Найти цитируемый пост)
$dbh->do("INSERT INTO ... VALUES ....", { PrintError => 0, RaiseError => 0 } );


Цитата(Ivan Kolesnikov @ 21.3.2006, 11:09 Найти цитируемый пост)
По моему, ты не в том месте используешь PrintError

smile

В do тоже можно, есть поле \%attr. Но лучше инициализировать аттрибуты в connect! Один раз и для всех методов!

Только
Код

use strict;
use DBI;
my $dbh = DBI->connect("dbi:mysql:database@localhost", $user, $password, {RaiseError => 0, PrintError => 0}); # отключение Raise!
$dbh->do("insert into ..."); # здесь можно ловить ошибки, если не ловить - то никаких ошибок не будет и ты не узнаешь, о выполнение команды.



Цитата(Ivan Kolesnikov @ 21.3.2006, 11:09 Найти цитируемый пост)
пример тоже выдает сообщение на консоль.

в STDOUT и у него тоже, только IDE перехватывает.

vax1700,
Цитата(vax1700 @ 21.3.2006, 00:20 Найти цитируемый пост)
Я так думаю, что в $dbh->do надо какой-то специальный флаг передавать, чтобы мускуловские ошибки не были фатальными для $dbh->do.

Нет, не надо! СУБД правильно ругается, ты - как разработчик должен предусмотреть такую ситуацию, раз в бд у тебя поле уникальное, чтобы не было duplicate!
Делаешь выборку, если такой записи нет, то вставляешь, если есть, то выводишь сообщение пользователю или дальше.

Лично я всегда использую {RaiseError =>1, PrintError => 1} и всем тоже советую!

smile

Автор: Ivan Kolesnikov 21.3.2006, 12:44
Перед тем как писать я прочитал perldoc smile
Но все равно, если указать {PrintError=>0} в do(), то ошибка выводится, а если в connect, то нет. Может я что-то не понимаю?

Автор: vax1700 21.3.2006, 13:27
Цитата(Ivan Kolesnikov @ 21.3.2006, 10:09 Найти цитируемый пост)
Попробуй вот так:

В DBI->connect() я тоже пробовал.
PrintError => 0 работает. Но работает каким образом? Он просто глушит вывод (только визуальный вывод) ошибок, но прерывание выполнения скрипта при этом всё-равно остаётся.
Я думал, что это может быть из-за IDE, запустил вот так:
Цитата
perl xxx.pl

И мне опять в консоли вывелись все эти "duplicate key" и скрипт прервался.
Цитата
# здесь можно ловить ошибки, если не ловить - то никаких ошибок не будет и ты не узнаешь, о выполнение команды.

Вот именно что у меня прерывается! Я даже DBI обновлял, всё-равно выводит ошибки и прерывается.
Цитата
Нет, не надо! СУБД правильно ругается, ты - как разработчик должен предусмотреть такую ситуацию, раз в бд у тебя поле уникальное, чтобы не было duplicate!

Дело в том, что это часть алгоритма.
Поясню: у меня в таблице список слов (уникальный список). Мне нужно добавлять слово.
Перед добавлением я должен узнать, а нет ли там его такого уже.
Я могу просто сначала сделать SELECT, а потом если он ничего не выберет, сделаю INSERT.
Однако каждый раз делать - SELECT - это сильно жирно. Тем более когда таблица большая.

Поэтому я выбрал другую стратегию: я вставляю слово сразу, если вставка вернёт ошибку, только тогда я делаю SELECT. А если нет, значит это новое слово.
Итого мы имеем, что для новых слов мы экономим очень ёмкий запрос.

Цитата
Но все равно, если указать {PrintError=>0} в do(), то ошибка выводится, а если в connect, то нет. Может я что-то не понимаю?

Вообщем-то мне даже всё-равно выводится она или нет. Дело не в выводе, а в том, что выполнение скрипта обраывается выдачей фатальной ошибки. И RaiseError => 0 не помогает smile

Автор: Ivan Kolesnikov 21.3.2006, 13:39
Код

use DBI;
use strict;
my $dbh = DBI->connect('connect', 'user', 'password', {PrintError => 0, RaiseError => 0});
$dbh->do("insert into...") or print "Can not insert\n";
print "OK";

У меня нормально работает, вне зависимости была ошибка или нет, выводится "OK"

Автор: vax1700 21.3.2006, 13:54
Ivan Kolesnikov,
А какую вы ошибку пробовали допустить?
У меня не получается на дублирование UNIQUE ключа.
Вы такую же ситуацию воспроизвели?

Автор: Ivan Kolesnikov 21.3.2006, 14:45
Да, но вот только у меня база не Mysql, а Oracle, сейчас проверю на mysql и сообщу свои результаты

Автор: vax1700 21.3.2006, 15:09
Прошу прощения, но по-моему наболомутил я.
Прерывается на regexp'е.....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)