g0n has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

Before reporting this to the author of the module, I'd like to run it past the collected monkish expertise, to see if I've overlooked something. I'm getting differing results from the same code when run using DBD::CSV and DBD::SQLite

I have the following test code:

use DBI; use strict; my $db = DBI->connect("DBI:CSV:"); # create table $db->do("create table testdb (NAME CHAR(20),POSTAL CHAR(20),TELEPHONE +CHAR(20))"); # create dummy data my $sth=$db->prepare("insert into testdb (NAME,POSTAL,TELEPHONE) VALUE +S (?,?,?)"); for (1..10) { $sth->execute("name $_","postal $_","telephone $_"); } # update 2 lines of data with different format statements my $sth1 = $db->prepare("update testdb set NAME=?,POSTAL=?,TELEPHONE=? + where name=?"); my $sth2= $db->prepare("update testdb set POSTAL=?,TELEPHONE=? where n +ame=?"); $sth1->execute("name 9","postaladdress","123456","name 9"); $sth2->execute("postaladdress","123456","name 10"); # display the contents of testdb my $sth3 = $db->prepare("select * from testdb"); my $result = $sth3->execute(); my $line; while ($line = $sth3->fetchrow_arrayref) { for my $attrib (@$line) { print "$attrib\t"; } print "\n"; }

(See below for output)

If I change the connect line as follows:

my $db = DBI->connect("DBI:SQLite:dbname=testfile","","");

I get a different result. This is the output using DBD::CSV

name 1 postal 1 telephone 1 name 2 postal 2 telephone 2 name 3 postal 3 telephone 3 name 4 postal 4 telephone 4 name 5 postal 5 telephone 5 name 6 postal 6 telephone 6 name 7 postal 7 telephone 7 name 8 postal 8 telephone 8 name 9 name 9 postaladdress name 10 name 10 postaladdress

and this is the output using DBD::SQLite

name 1 postal 1 telephone 1 name 2 postal 2 telephone 2 name 3 postal 3 telephone 3 name 4 postal 4 telephone 4 name 5 postal 5 telephone 5 name 6 postal 6 telephone 6 name 7 postal 7 telephone 7 name 8 postal 8 telephone 8 name 9 postaladdress 123456 name 10 postaladdress 123456

As you can see, the lines that have been changed in the DBD::CSV test are corrupt, whereas the corresponding lines in the DBD::SQLite test are correctly updated.

Am I tripping over an incorrectly formatted statement that DBD::SQLite forgives me for, and DBD::CSV doesn't, or is there a bug in DBD::CSV?

thanks,

Update: I'm running perl 5.8.7, and installed both DBD::CSV and DBD::SQLite using cpan install last night, so they should both be bang up to date.

Update:Versions:

DBD::CSV - 0.22
SQL::Statement - 1.14
DBI - 1.48
DBD::File - 0.33
Text::CSV_XS - 0.23

OS is linux

--------------------------------------------------------------

g0n, backpropagated monk

Replies are listed 'Best First'.
Re: Bug in DBD::CSV?
by jZed (Prior) on Sep 06, 2005 at 15:30 UTC
    Yes, sorry, it probably is a bug (in SQL::Statement) that occurs sporadically when using UPDATE with placeholders. I am in the process of rewriting the code now. For the time being, avoid using placeholders with UPDATE or else revert to SQL::Statement 1.09. I'll try to have a new release out this week. For what it's worth, I apparently introduced the bug when optimizing placeholder performance and it only occurs in some very specific situations so it's hard to test for.
      Ahh, OK, thanks. I've got a usable workaround for the time being, and I'll upgrade SQL::Statement when you release the fix.

      Thanks for the quick confirmation :-)

      --------------------------------------------------------------

      g0n, backpropagated monk

Re: Bug in DBD::CSV?
by Tortue (Scribe) on Sep 06, 2005 at 12:21 UTC
    Hi, I don't get the bug when I run your program on my system, which is Win XP, Perl 5.8.7, ActiveState Build 813, with these DBD::CSV-related module versions:
    DBI 1.46 Text::CSV_XS 0.23 SQL::Statement 1.09 DBD::File 0.34 DBD::CSV 0.22
    The output for CSV and for SQLite are identical. And your SQL looks OK to me.
Re: Bug in DBD::CSV?
by davidrw (Prior) on Sep 06, 2005 at 12:36 UTC
    Can you change the first value in $sth2->execute("postaladdress","123456","name 10"); to "postaladdress10" and say what the DBD::CSV output is? i'm curious which update statement really sets it .. hmm.. what happens in the update's are reversed in order? (i agree w/Tortue that the SQL looks good)

    I'm sure he'll see this, but in case he doesn't, be sure to /msg jZed or catch him in the chatterbox -- he's the author and always very willing to handle issues w/DBD::CSV ...

    random tmtowtdi code comment -- output could just be print join("\t",@$line), "\n"; instead of the foreach loop.
      OK

      .. $sth1->execute("name 9","postaladdress","123456","name 9"); $sth2->execute("postaladdress10","123456","name 10"); ..

      results

      name 1 postal 1 telephone 1 name 2 postal 2 telephone 2 name 3 postal 3 telephone 3 name 4 postal 4 telephone 4 name 5 postal 5 telephone 5 name 6 postal 6 telephone 6 name 7 postal 7 telephone 7 name 8 postal 8 telephone 8 name 9 name 9 postaladdress name 10 name 10 postaladdress10

      Thanks for the suggestions, I'll /msg jZed, and the join for output is much neater :)

      --------------------------------------------------------------

      g0n, backpropagated monk

Re: Bug in DBD::CSV?
by etm117 (Pilgrim) on Sep 06, 2005 at 13:04 UTC
    g0n, Since no one else has stated that they could replicate this...

    I was able to replicate your error with the exact output as you. (hopefully) this confirms for you its not a random issue with your local Perl install.

    Setup:
    ActiveState Perl, v5.8.6, build 811
    DBI, v1.48
    DBD::CSV, v0.22
    DBD::File, v0.34
    SQL::Statement, v1.14
    DBD::SQLite, v1.09
    Text::CSV_XS, v0.23

Re: Bug in DBD::CSV?
by davidrw (Prior) on Sep 06, 2005 at 13:13 UTC
    Using DBD::CSV 0.21, it works iff i change the UPDATE's to be "WHERE NAME=?" (otherwise i get a "unknown column" error)-- apparently it is case sensitive ... dunno if this is by design or a bug (taking a fast glance at SQL::Statement's source, though, it looks like there's support in there for case-insensitivity)..

    Any additional information if you turn RaiseError on w/$dbh->{'RaiseError'} = 1; (or in DBI->connect call)?
      I tried setting NAME to caps. That made no difference. Swapping the two prepares round makes no difference, and neither does swapping the two executes round.

      No errors either with RaiseError! V strange....

      --------------------------------------------------------------

      g0n, backpropagated monk