On Wed, Mar 03, 2004 at 03:50:14PM +0100, Kristian Nielsen wrote:
> Tim Bunce <[EMAIL PROTECTED]> writes:
> 
> > Or, looking at it a different way, does this work:
> > 
> >     $sth = $dbh->prepare("INSERT INTO mytable VALUES( :foo )");
> >     $sth->bind_param_array(":foo", [0..9999]);
> >     $s->execute_array(undef);
> > 
> > It ought to.
> 
> It does not:
> 
>     DBD::Oracle::st bind_param_array failed: Can't use named placeholders for 
> non-driver supported bind_param_array [for Statement "INSERT INTO mytable 
> VALUES(:foo)" with ParamValues: :foo=undef] at -e line 1.
> 
> And in fact it cannot work using the execute_for_fetch() approach. It
> has been too long so I had forgotten, but now I remember: this is
> actually the main reason I originally decided to implement execute_array
> directly rather than just execute_for_fetch(). Named placeholders for
> execute_array requires column_wise bind values. Rowwise as in
> execute_for_fetch() doesn't have the bind names.

D'oh. Right.

> This could be fixed, of course: execute_for_fetch could let the
> $fetch_tuple_sub return hash references, or bind_param_array() could set
> up a mapping from names to placeholder indexes.
> 
> Hm, I'll have to think about that. Any suggesions?

$sth->{ParamValues} may be the answer. Not quite sure about a good
interface though.

> > > +static int
> > > +do_bind_array_exec(sth, imp_sth, phs)
> > 
> > Beyond here it looks like you've done more work than needed. I was
> > expecting the dbd_phs_in() callback function to be extended (slightly)
> > so it knew how to use the oracle supplied index to index into the array.
> 
> As I said it has been a long time, but I'll try to remember back then ...
> 
> There are two parts to binding. One is to setup the proper OCI callbacks
> (dbd_phs_id ...). The other is to convert the bind values from Perl
> scalars to char *'s.
> 
> For non-array bind, DBD::Oracle mixes these two together, as far as I
> remember. But for array bind the OCI callbacks must be set up once, but
> the conversion to char * must be done once for each bind value. So I had
> to implement new array bind code to set up the callback, and extend
> dbd_phs_in() with the char * conversion.
> 
> If you want, maybe I could look into instead special-casing the
> non-array bind code to do only the callback-setup in the array case?
> Maybe originally I just felt that the bind code was complicated enough
> as it is. But the char * conversion must stay in the callback (unless we
> want to allocate a whole new array with the converted values ...). Maybe
> /all/ char * conversion should move into the callback?

I think that's a good way forward.

> Anyway, I am all for trying to make the code simpler, so I'll look
> deeper into your suggestions and welcome any further input.

That would be great. Thanks.

Tim.

Reply via email to