开发者

Perl DBI: how to see failed query with bound values?

This is a standard inserting example from DBI manual:

     my $query = q{
       INSERT INTO sales (product_code, qty, price) VALUES (?, ?, ?)
     };
     my $sth = $dbh->prepare($query) or die $dbh->errstr;
     while (<>) {
         chomp;
         my ($product_code, $qty, $price) = split /,/;
         $sth->execute($product_code, $qty, $price) or die ($query . " " . $dbh->errstr);
     }
     $dbh->commit or die $dbh->errstr;

I modified it a bit, so I can see on die which query failed (die ($query . " " . $dbh->errstr)). Still I'd liked to see the query with bound values (as it was executed). How to get it?


Edit

Btw, i found a awkward way to see query with bound values too: you have to make syntax error in query. For example, if i change query above like that:

     my $query = q{
       xINSERT INTO sales (product_code, qty, price) VALUES (?, ?, ?)
     };

I got it back as i wanted:

DBD::mysql::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xINSERT INTO sample (product_code, qty, price) VALUES ('1', '2', '3')' at line 1

Sometimes it really helps. At least it did to m开发者_运维问答e.


You can use DBI's ParamValues to obtain the parameter values but you are unlikely to find any method in a DBD to obtain the parameters actually in the SQL because they are mostly sent to the database after the SQL is parsed. You can look at DBIx::Log4perl to see how ParamValues is used in the error handler. You might also find some parts of DBIx::Log4perl useful.


There isn't a standard way to do that. The nearest approximation would be to substitute each placeholder by the (probably quoted) value. In general, it is fairly hard to reliably parse an SQL statement to find the question marks that are placeholders rather than parts of delimited identifiers or strings or comments. In the example, you can simply look for question marks; that won't always work, though:

INSERT /* ? */ INTO "??".Sales VALUES('?', ?, ?, ?);

Note that with most, but not necessarily all, DBMS (and hence most DBD drivers), the statement is sent to the DBMS when it is prepared; only the values are sent when the statement is executed. There never is a statement created with all the values substituted into the VALUES list, so neither DBI nor the DBMS should be expected to create one.


There isn't any generically supported DBI way to do this, I think, but individual database drivers might allow it. What database are you using?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜