Re: Keeping Perl DBI Quiet
by Zed_Lopez (Chaplain) on Nov 25, 2003 at 18:33 UTC
|
Many perl modules' routines die when something goes wrong.
DBI shouldn't unless you set RaiseError => 1 when you did your database handle connect.
The standard technique for dealing with such routines is:
eval {
potentially_fatal_function_call();
}
if ($@) {
print "Fatal Error: $@";
# ... whatever other appropriate error recovery
}
Wrapping the potentially fatal function call in an eval block means that if it dies, your program won't stop; it'll just set $@ and you can check it.
I recommend leaving RaiseError => 1 and trapping the errors yourself.
There's a current thread on formatting this idiom.
| [reply] [d/l] [select] |
|
|
In addition to RaiseError, the OP might want to take a look at PrintError. Usage is the same.
| [reply] |
Re: Keeping Perl DBI Quiet
by jdtoronto (Prior) on Nov 25, 2003 at 19:17 UTC
|
I don't have the docs in front of me, but read the DBI docs. Basically what you need to do is turn attributes 'raiserror' and 'printerror' off.
Personally, however, I would never do that. Why not test the tables, see if they are there and then remove them. You can get the errors into your programme, but why do you have to do anything with them? If they are about things like attempt to write a duplicate record or such, you can sensibly choose what to ignore and what to take seriously.
A missing table is not an error to necessarilly die for. But it is that sort of behaviour in PHP which keeps many Perl programmers from using it. My in-house PHP hacker searched for several hours the other day to find out why his script wouldn't write teh data it was supposed to... he wasn't trapping any errors and the table was not present... his table creation code had not worked but he did not realise it.
jdtoronto
| [reply] |
Re: Keeping Perl DBI Quiet
by iburrell (Chaplain) on Nov 25, 2003 at 19:49 UTC
|
There are two attributes of the database handle which control how DBI handles errors. RaiseError causes DBI to die on an error. PrintError causes DBI to warn on an error. The default has PrintError on and requires checking each call for errors. To save checking each call, it is common to turn RaiseError on and PrintError off.
It is possible to turn of both of them off. This is dangerous because it is easy to forget to check a database call and wonder why your code is not working. I suggest turning off error reporting only for the statements you know might fail:
{
local $dbh->{RaiseError} = 0;
local $dbh->{PrintError} = 0;
$dbh->do($sql_that_might_fail);
}
| [reply] [d/l] |
Re: Keeping Perl DBI Quiet
by b10m (Vicar) on Nov 25, 2003 at 18:33 UTC
|
I had a fuss with DBI too, when I wanted to insert a lot of rows. If a row was already there, DBI would spit out errors (as it should), but it was not what I wanted. I didn't care if the row couldn't be inserted, I only wanted them in there once anyways. I used the following to solve it (note the OR IGNORE):
$dbh->prepare_cached("INSERT OR IGNORE INTO table VALUES (?,?,?,?)");
(Note: This was used with DBD::SQLite)
HTH
| [reply] [d/l] |
|
|
my $sth = $dbh->prepare('INSERT IGNORE INTO table VALUES(?,?,?);
$sth->execute(@foo);
| [reply] [d/l] |
Re: Keeping Perl DBI Quiet
by cleverett (Friar) on Nov 26, 2003 at 05:43 UTC
|
If you're running MySQL, try:
my @temp_tables = qw/foo bar bax quux/;
my %tables = map { $_ => {} }
@{$dbh->selectall_arrayref("show tables", {Columns =>
+ {}})};
foreach (@temp_tables) {
$dbh->do("drop table $_") if exists $tables{$_};
}
The usual caveats apply WRT being careful about not dropping tables at random, etc.
If you're not using MySQL, perhaps the RDBMS you are using has an equivalent.
HTH | [reply] [d/l] |
Re: Keeping Perl DBI Quiet
by EvdB (Deacon) on Nov 26, 2003 at 09:00 UTC
|
If you are using Postgres you can create temporary tables with CREATE TEMP TABLE table_name .... These tables will only last until the end of the users session and then be deleted automatically. If you keep the connection to the database open for the whole lifetime of your app this may be useful.
--tidiness is the memory loss of environmental mnemonics
| [reply] [d/l] [select] |
|
|
And if you just happen to be using mysql instead of Postgres, you're in luck. Slightly different syntax, but it's available (darn the cross-compatability, why can't they all be the same? :)).
# for mysql temporary table (exists until end of session)
CREATE TEMPORARY TABLE table_name(
...
);
| [reply] [d/l] |
|
|
Actually I was being lazy, the form you gave is good for Postgres too.
--tidiness is the memory loss of environmental mnemonics
| [reply] [d/l] |