Tim Bunce <[EMAIL PROTECTED]> writes:

> > +            my $res = ora_execute_array($sth,
> > +                                        [EMAIL PROTECTED],
> > +                                        scalar(@tuple_batch),
> > +                                        $tuple_batch_status);
> > +            if(defined($res) && defined($row_count)) {
> > +                $row_count += $res;
> > +            } else {
> > +                $row_count = undef;
> > +            }
> > +            push @$tuple_status, @$tuple_batch_status
> > +                if defined($tuple_status);
> > +        }
> > +        return $row_count;
> 
> I think the return value isn't right. I'd there's an error then do ++$err_count,
> then on return do: return ($err_count) ? undef : scalar @$tuple_status;

If there is an error ora_execute_array() returns undef, and $row_count
is set to undef. If there is no error $row_count will be sum of
individual ora_execute_array() rowcounts. But I will see if your
suggestion can work and if so change to that for clarity.

> 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.

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?

> > +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?

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

 - Kristian.

-- 
Kristian Nielsen   [EMAIL PROTECTED]
Development Manager, Sifira A/S

Reply via email to