Database Reference
In-Depth Information
prints its own message. This is redundant, as well as confusing to the person using the
script.
If you enable
RaiseError
, you can call DBI methods without checking for return values
that indicate errors. If a method fails, DBI prints an error and terminates your script. If
the method returns, you can assume it succeeded. This is the easiest approach for script
writers: let DBI do all the error checking! However, if both
PrintError
and
RaiseEr
ror
are enabled, DBI may call
warn()
and
die()
in succession, resulting in error mes‐
sages being printed twice. To avoid this problem, disable
PrintError
whenever you
enable
RaiseError
:
my
$conn_attrs
=
{
PrintError
=>
0
,
RaiseError
=>
1
,
AutoCommit
=>
1
};
my
$dbh
=
DBI
->
connect
(
$dsn
,
"baduser"
,
"badpass"
,
$conn_attrs
);
This topic generally uses that approach. If you don't want the all-or-nothing behavior
of enabling
RaiseError
for automatic error checking versus having to do all your own
checking, adopt a mixed approach. Individual handles have
PrintError
and
RaiseEr
ror
attributes that can be enabled or disabled selectively. For example, you can enable
RaiseError
globally by turning it on when you call
connect()
, and then disable it
selectively on a per-handle basis.
Suppose that a script reads the username and password from the command-line argu‐
ments, and then loops while the user enters statements to be executed. In this case, you'd
probably want DBI to die and print the error message automatically if the connection
fails (you cannot proceed to the statement-execution loop in that case). After connect‐
ing, however, you wouldn't want the script to exit just because the user enters a syntac‐
tically invalid statement. Instead, print an error message and loop to get the next state‐
ment. The following code shows how to do this. The
do()
method used in the example
executes a statement and returns
undef
to indicate an error:
my
$user_name
=
shift
(
@ARGV
);
my
$password
=
shift
(
@ARGV
);
my
$conn_attrs
=
{
PrintError
=>
0
,
RaiseError
=>
1
,
AutoCommit
=>
1
};
my
$dbh
=
DBI
->
connect
(
$dsn
,
$user_name
,
$password
,
$conn_attrs
);
$dbh
->
{
RaiseError
}
=
0
;
# disable automatic termination on error
print
"Enter statements to execute, one per line; terminate with Control-D\n"
;
while
(
<>
)
# read and execute queries
{
$dbh
->
do
(
$_
)
or
warn
"Statement failed: $DBI::errstr ($DBI::err)\n"
;
}
If
RaiseError
is enabled, you can execute code within an
eval
block to trap errors
without terminating your program. If an error occurs,
eval
returns a message in the
$@
variable:
eval
{
# statements that might fail go here...
};