On Tue, Sep 05, 2006 at 11:20:04AM +0100, Martin J. Evans wrote:
> 
> I'll report the problems just as soon as I'm certain what they are. Here is
> my summary:
> 
> 1. insert into table values (?,?) where all values are valid and 3 rows of
>    values
> 
>      returns: 3
>        (correct as 3 tuples executed)
>      ArrayTupleStatus = (-1, -1, -1)
>        (incorrect - should be (1,1,1) as DBD::Oracle does know a row was
>         inserted each time as evidenced by execute itself which returns rows
>         affected)
> 
> 2. insert into table values (?,?) where there are 2 rows of data but second 
> one
>    is invalid
> 
>    returns: undef
>      (correct)
>    ArrayTupleStatus = (-1, [1772, 'ORA-01722.......'])
>      (incorrect as this should be (1, [1772, 'ORA-01722.......'])
>       probably same issue as 1).
> 
> 3. update table where the update does not affect any rows
> 
>    returns: 0
>      (incorrect - should be 1 for 1 tuple executed)
>    ArrayTupleStatus = (-1)
>      (incorrect - should be (0) for no rows affected)
> 
> If my conclusions look right to you I'll report them on rt.

You're spot on.

> As an aside, I am finding execute_array returning the number of tuples 
> executed
> rather than the number of rows affected a bit of a pain. It seems to make it
> easy to ascertain how many tuples were executed but hard to find out how
> many rows were affected when I would have thought the former is less useful
> and easily calculated as [EMAIL PROTECTED]). What I normally do on a
> single insert/update execute is:
> 
> $affected = $sth->execute(@params)
> ERROR if ($affected != $expected_inserts_or_updates);
> 
> as this catches errors in the execute and error in the program logic (not
> inserting/updating what I expected). execute_array does not map easily to 
> being
> n * execute as far as I can see since the equivalent test for execute_array 
> is:
> 
> $tuples_executed = $sth->execute_array
> if (!$tuples_executed) {
>   # there was an error
> } else {
>   # here $tuples_executed has no meaning for me since I know what it is going
>   # to be before calling execute_array - it is going to be the number of 
> tuples
>   # I passed to execute_array
>   my $affected = 0;
>   $affected += $_  foreach (@array_tuple_status);
>   ERROR if ($affected != $expected_inserts_or_updates)
> }
> 
> It's possible I've misunderstood what is returned by execute_array but it is
> difficult to actually try it out when I don't seem to have a driver that does
> it properly.

The DBIs default behaviour is the official behaviour.

I take your point about the return value. I remember weighing up both
alternatives before settling on 'tuples executed' - but I can't now
remember why! I probably also didn't consider bulk updates as a likely
use case.

How about adding total rows affected as an extra return value in list
context?:

  ($tuples_executed, $rows_affected) = $sth->execute_array(...)

Tim.

Reply via email to