Tim Bunce wrote:
On Wed, Mar 29, 2006 at 09:02:43PM +0100, Martin J. Evans wrote:

Thanks Tim. I'm now hopefully looking in the right places.

Not seeing execute on a selectrow_array threw me initially
but it is an example of the problems I'm seeing.

I'm having a few problems accessing things at the time I want.

e.g. execute_array can be called with the parameters (which I
want to see) and this is ok, but can also be called with
bind_param_array then execute_array but in this case
sth->{Params} does not contain the parameters after the sth->SUPER::execute_array call (I was suprised by that).


Looking at the code for bind_param_array I see the bound refs are
stored in $sth->{ParamArrays}.

Thanks, you've found me out, should have looked harder myself.
I've got some excuses but I'll not bore the list with them.


This is a problem for me since I want to examine the
tuple_status passed to execute_array and find the
parameters for the execute which failed. I've found another
way around this for now by moving the code which highlights
the parameters which failed into execute.


I'd accept a doc patch to document the ParamArrays attribute.

I'll accept that as my penalty for laziness ;-)

I've tested this in my code and with reference to the other problem
I posted with dbd::mysql Data::Dumper->Dump([$sth->{ParamArrays}], 'ParamArrays']) correctly shows:

$ParamArrays = {'1' => [51,1,52,53],'2' => ['fiftyone','fiftytwo','fiftythree','one']};

Just the ticket - cheers.


Just to put some context on this I'm suclassing DBI as something
like DBIx::Log4Perl where all the SQL, parameters, fetched data,
transactions, error handler can be logged. I'm doing this because I
have a large Perl server accepting a huge number of jobs per second
which is very transaction heavy. It is impossible to debug since
it is almost impossible to reproduce the condition which caused the
error so I need as much info as possible at the time of the problem
and I need it as light weight as I can make it because slowing it
down sometimes hides the problem.


Sounds interesting.

Tim.

I don't want to make any promises right now since I'm very time poor
at the mo but if I find it works out for us I'll make it available.

Martin


Tim Bunce wrote:

On Wed, Mar 29, 2006 at 04:49:32PM +0100, Martin J. Evans wrote:


Tim,

Thanks, I do keep forgetting about Driver.xst.

So, just to be clear. In DBI.pm, selectrow_array calls _do_selectrow which
calls prepare/execute/fetchsomething but this may be overriden by a driver
using selectrow_array in Driver.xst. If this is the case:

a) is there any way for my subclassed DBI to know this?


Something like this might work:

 ... if exists &DBD::foo::db::selectrow_array;

Also, take a look at the docs for the DBI's can() method. Though if you
want to rely on that you might want to look into the implementation to
check for edge cases or other subtle issues.



b) is there an easy way to identify which other methods this could apply to


Nope. You'd have to use the above on all of them.

Tim.



Martin
--
Martin J. Evans
Easysoft Ltd, UK
http://www.easysoft.com


On 29-Mar-2006 Tim Bunce wrote:


On Wed, Mar 29, 2006 at 11:54:32AM +0100, Martin J. Evans wrote:


The issue I am seeing is not quite as general as I made it sound. For
selectrow_hashref I see prepare/execute/fetch/fetchrow_hashref (as I expect)
but
for selectrow_arrayref and selectrow_array I only see prepare.

Generally... Drivers are free to implement any method in any way they choose.
Their own methods don't have to call execute(), for example.

Specifically... you're probably seeing the effect of the Driver.xst
C code that most compiled drivers embed into themselves. That code
embeds C implementations of selectall_arrayref and several other
methods into the driver itself. The selectall_arrayref code calls the
drivers C functions to do the work. The result is much, much, faster
than going though perl/DBI method dispatch for each row.

Tim.



Martin
--
Martin J. Evans
Easysoft Ltd, UK
http://www.easysoft.com


On 29-Mar-2006 Martin J. Evans wrote:


Hi,

I have subclassed DBI and override many methods including prepare, execute
and
select* although they are predominantly just passed on to DBI.

If I do:

my $sth->prepare(sql);
$sth->execute;

I see the prepare and execute and pass them on to DBI.

If I do:

$dbh->selectrow_array(sql);

I see prepare and pass it on, but do not see execute. In my case this is
more
than an annoyance as I cannot see any bound parameter passed to execute.

e.g.

$selectrow_array = [
                  'select b from mytest where a = ?',
                  undef,
                  \1
                ];
prepare: select b from mytest where a = ?
!!! no execute here

Or, perhaps I'm doing something wrong.

Can anyone tell me if I should be seeing the execute when $dbh->select***
is
called? I think I should.

Thanks

Martin
--
Martin J. Evans
Easysoft Ltd, UK
http://www.easysoft.com

Reply via email to