Let's say I have a subroutine that connects to a DB. Then I want to make a query and receive the output and do something with it, of course, but what if the query is invalid?
So let's assume I have something like:
$dbh = DBI->connect(<db>, <user>, <pass>);
$query = 'select a, b, c from table';
$sth = $dbh->prepare($query);
$sth->execute();
I realise I could also use a "do", but this will be easier for me to understand. So in a scenario where "table" doesn't have a column "c", the query would be invalid, making the handle $sth invalid and failing to execute. Right?
Now, in case of a failure as such, what happens to $sth? I can't call finish on it, because it is invalid.
This is by far the best way to do things. Stick with prepare
(which you need to do only once) and execute
and avoid do
. You should also use question marks as placeholders for any parameters to the query and pass the values in the call to execute
. Amongst other things, that way handles any necessary quoting of the values for you
It is very rare that a call to finish
or disconnect
is necessary. You should leave them out until you know your way around DBI
better
You're correct, $sth
will be undef
, and the error code and error message will be returned by $dbh->err
and $dbh->errstr
. Also, by default the PrintError
option is set, which causes DBI
to generate a warning if there are any errors in execution. If you want your program to stop altogether instead then disable PrintError
and enable RaiseError
Apart from that it's really down to what you choose to do in the case of an error. For instance, some errors might be recoverable, in which case you can disable both PrintError
and RaiseError
and test whether the returned value is undef
. Then you would perform some action possibly based on the error code returned by $dbh->err
I hope that helps
So in a scenario where "table" doesn't have a column "c", the query would be invalid, making the handle $sth invalid and failing to execute. Right?
It's not clear what you mean by "invalid".
Some drivers, like DBD::Oracle, may send the SQL statement to the server when you call prepare
, in which case the error will be detected by the server and prepare
will fail, returning an undef. (See also @Borodin's note about RaiseError.)
If the driver doesn't send the statement to the server when prepare
is called then driver creates and returns a statement handle that has the statement string stored within it.
Now, in case of a failure as such, what happens to $sth? I can't call finish on it, because it is invalid.
Again, it's not clear what you mean by "invalid". (I find it helpful to try to be really clear about the concepts and situations I'm thinking about. Forcing myself to do that often means I find the answers to my own questions because the 'problem' was in the words I was using.)
So, as I described above, either prepare
failed and returned an undef (or threw an exception due to RaiseError - recommended), or prepare
returned a valid $sth.
If prepare
returned an undef then perl will throw an exception when you try to call execute.
If prepare
returned a valid $sth then execute
will be called, the statement will be sent to the server, the server will detect the error, and execute
will return false (or throw an exception if RaiseError is set - recommended).
At no point would I call $sth "invalid". Either you don't have an $sth at all because prepare failed, or you have an $sth that's perfectly valid but experienced an error when executed.
In that case calling $sth->finish
would work but, as @ThisSuitIsBlackNot correctly noted, it would be pointless. (I should have renamed finish
to discard_pending_rows
many many years ago.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.