On Tue, Sep 19, 2006 at 01:41:22PM -0700, Dean Arnold wrote:
> I stumbled on an oddity in execute_array() I'm hoping can
> be clarified (it maybe a bug, or just an undoc'd requirement
> of driver authors)
> 
> The following bit of code appears to require that the hash returned by
> ParamArrays use monotonically increasing integers as keys:
> 
> 
>           my %hash_of_arrays = %{$sth->{ParamArrays}};
>             ....some code here....
>           my @bind_ids = 1..keys(%hash_of_arrays);
> 
>           my $tuple_idx = 0;
>           $fetch_tuple_sub = sub {
>               return if $tuple_idx >= $maxlen;
>               my @tuple = map {
>                   my $a = $hash_of_arrays{$_};
>                   ref($a) ? $a->[$tuple_idx] : $a
>               } @bind_ids;
>               ++$tuple_idx;
>               return [EMAIL PROTECTED];
>           };
> 
> But the ParamArrays docs indicate that the returned hash can
> use something other than integers as keys.

Umm. Good point.

It's related to the fact that if you use 'named' placeholders with a
non-array statement then you have to use bind_param() and not supply
any bind values to execute().

The problem with execute_array is that it's built on execute_for_fetch
and that requires an ordered set of bind values.

> I've worked around this by implementing an internal mapping
> so that named parameters have a matching positional value,
> which is used when ParamArrays/ParamValues are assigned
> within bind_param{_array]().

> So...bug, or requirement ? I don't know if anything can be
> done to correct it without some new DBI attribute to provide
> the parameter name-to-position mapping, so I'm guessing
> its a requirement, and maybe ParamArrays (and ParamValues and ParamTypes)
> need doc updates to remove the 'flexible' definition ? Or is a new
> attribute preferable ? or maybe just an extension to ParamTypes to include
> a POSITION attribute ? Or maybe the requirement is that drivers w/ named
> placeholders have to implement their own execute_array() ?

I think I'm going to take the view that all drivers should support
'?' style placeholders and that those should be used for execute_array
and execute_for_fetch.

For database that don't support '?' style placeholders it's pretty
trivial for the driver to rewrite them as 'p1', 'p2' etc etc.
That's exactly what DBD::Oracle as always done.

Could you update the docs? (If you don't have write access to the dbi
repository yet, send me your auth.perl.org username and I'll give it to you.)

Tim.

Reply via email to