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

Ok here's the dilly-yo.

I've got a Perl app using DBI with a MySQL database. I keep getting an error and I can't spot why(neither can my boss). So I'm wondering if there are any bugs with our versions of DBI or DBD::mysql(or my app for that matter ;).

Okay here's code in abbreviated form. The parts that involve the error are exact:

use DBI; use strict; # query in question my $sth_sts = $dbh->prepare("UPDATE players SET t_id=?, bats=?, throws +=?, status=? WHERE id=?"); my $i; foreach $i (0 .. $#$prec) { # $prec is defined elsewhere # blah # blah # blah # blah # execute in question $sth_sts->execute($tid,$p->{P_BATS},$p->{P_THROWS},$p->{P_STATUS}, +$p->{P_PLAYERID}) or print "$DBI::errstr\n"; # blah }
And the error:
Unknown column 'R' in 'field list'
And a sample of what the values plugged into the query should be:
$tid = 20; # or any other 2 digit int $p->{P_BATS} = 'R'; # or 'L','S' $p->{P_THROWS} = 'R'; # or 'L' $p->{P_STATUS} = 'A'; # or 'D','I','M' $p->{P_PLAYERID} = 1846404; # or any other int up to 10 digits

Also, I figured you'd probably like to know the versions of DBI and DBD::mysql...oh and Perl ;)

Again, I'm at a complete loss. I thought it might be a problem with the quoting of the variables(which still seems likely to me), but I can't figure out where the problem is occuring or how to fix it.

Thanks in advance.

Amel - f.k.a. - kel

Replies are listed 'Best First'.
Re: DBI/DBD::mysql bugs?
by Fletch (Bishop) on Apr 09, 2002 at 18:07 UTC

    Enable tracing on the statement handle in question; a value of `2' usually will show what's going to and from the database backend. That'll show you what DBI is sending to mysql and you can see if something's not getting quoted correctly. You might have to use bind_param and explicitly set the type of one of the variables if it's not getting determined correctly automagically.

Re: DBI/DBD::mysql bugs?
by dws (Chancellor) on Apr 09, 2002 at 18:08 UTC
    Are you really, really sure that there's no code path that would bypass that prepare()? The error message you're getting is one that I've only seen from attempts to do an INSERT with an error in the column list.

Re: DBI/DBD::mysql bugs?
by perlplexer (Hermit) on Apr 09, 2002 at 18:26 UTC
    At what point in your program do you get that error?
    Do you have RaiseError set to 1 ? If not then the only place where the program can die() is where you call execute()...

    Anyway, I would try calling prepare() and execute() using hardcoded values just to make sure you don't have a fubar'ed version of DBI/DBD.
    If you get a meaningful result, start adding your $p->{blah} variables one-by-one and see when it breaks...
    Hope this helps.

    --perlplexer

      I used your and Fletch's suggestions and here's what I came up with.

      1. Setting a tracelevel of 2 on the problem statement handle pretty much confirmed that DBI is having a quoting problem. The single char strings are not getting quoted(ironically, the 5-8 digit int is :) Well I think we all pretty much knew that was part of the problem based on the error message.
      2. I used hardcoded values in the prepare statement and it worked fine. As soon as I used the placeholders though, everything goes bad. NONE of the string values are being treated as such. 3. I tried explicitly binding the parameters but to no avail. Still the chars are not quoted.

      I did get it to work using the 'do' method, but that is less efficient since the statement is executed inside a loop. Now the statement has to be prepared each time through the loop(which is better than not working at all I suppose :). Still though, for efficiency's sake I'd rather use the 'prepare-execute' method, so I'd still like to figure this out.

      Anyway, here's what the trace on the statement handle output to STDOUT:

      DBI::st=HASH(0x87b0d80) trace level set to 2 in DBI 1.13-nothread Note: perl is running without the recommended perl -w option SANFRNCSCO**** -> bind_param for DBD::mysql::st (DBI::st=HASH(0x83dd82c)~0x87b0d8 +0 1 undef) <- bind_param= 1 at bb_ps_stats.pm line 49. -> bind_param for DBD::mysql::st (DBI::st=HASH(0x83dd82c)~0x87b0d8 +0 2 R) <- bind_param= 1 at bb_ps_stats.pm line 50. -> bind_param for DBD::mysql::st (DBI::st=HASH(0x83dd82c)~0x87b0d8 +0 3 R) <- bind_param= 1 at bb_ps_stats.pm line 51. -> bind_param for DBD::mysql::st (DBI::st=HASH(0x83dd82c)~0x87b0d8 +0 4 A) <- bind_param= 1 at bb_ps_stats.pm line 52. -> bind_param for DBD::mysql::st (DBI::st=HASH(0x83dd82c)~0x87b0d8 +0 5 '10457') <- bind_param= 1 at bb_ps_stats.pm line 53. -> execute for DBD::mysql::st (DBI::st=HASH(0x83dd82c)~0x87b0d80) -> dbd_st_execute for 083dd634 Binding parameters: UPDATE players SET t_id=NULL, bats=R, throws +=R, status=A WHERE id='10457' Unknown column 'R' in 'field list' error 5 recorded: Unknown column 'R +' in 'field list' <- dbd_st_execute -2 rows !! ERROR: 5 'Unknown column 'R' in 'field list'' <- execute= undef at bb_ps_stats.pm line 54. -> $DBI::errstr (&) FETCH from lasth=DBI::st=HASH(0x87b0d80) No status UPD: Unknown column 'R' in 'field list' -> DESTROY for DBD::mysql::st (DBI::st=HASH(0x87b0d80)~INNER) <- DESTROY= undef at unknown location!
      Doesn't reveal anything new to me but who knows what you'll see.

      Thanks again.

      Amel - f.k.a. - kel

        Can you upgrade to a newer version of DBI ?
        The latest one is 1.21, I believe.
        The following code works on my Win2K PC (cygwin, PostgreSQL, DBI 1.201, ActivePerl 5.6.1)
        use DBD::ODBC; use DBI; my $p = {}; my $t_id = '20'; $p->{P_BATS} = 'R'; $p->{P_THROWS} = 'R'; $p->{P_STATUS} = 'A'; $p->{P_PLAYERID} = 1; my $dbh = DBI->connect('DBI:ODBC:test', 'foo', 'bar', {RaiseError => 1 +}); my $sth = $dbh->prepare(qq/UPDATE players SET t_id=?, bats=?, throws=? +, status=? WHERE id=?/); $sth->execute($t_id, $p->{P_BATS}, $p->{P_THROWS}, $p->{P_STATUS}, $p- +>{P_PLAYERID}); $sth = $dbh->prepare(qq/SELECT * FROM players/); $sth->execute(); while (my @row = $sth->fetchrow_array()){ print join(',', @row),"\n"; } $dbh->disconnect();
        Table 'players' is defined as follows
        test=# \d players Table "players" Attribute | Type | Modifier -----------+-----------------------+---------- id | integer | t_id | character varying(20) | bats | character varying(20) | throws | character varying(20) | status | character varying(20) |

        --perlplexer
Re: DBI/DBD::mysql bugs?
by perlplexer (Hermit) on Apr 10, 2002 at 03:08 UTC
    I added the following loop to simulate what was happening in your program
    for (keys %$p){ if ($p->{$_} == 0){} }
    I still got no errors.
    Trace:
    DBI 1.201-nothread dispatch trace level set to 2 Note: perl is running without the recommended perl -w option -> prepare for DBD::ODBC::db (DBI::db=HASH(0x1abae48)~0x1abad7c 'U +PDATE players SET t_id=?, bats=?, throws=?, status=? WHERE id=?') dbd_preparse scanned 5 distinct placeholders dbd_st_prepare'd sql f31660176 UPDATE players SET t_id=?, bats=?, throws=?, status=? WHERE id=? <- prepare= DBI::st=HASH(0x1abae6c) at a.pl line 18 -> execute for DBD::ODBC::st (DBI::st=HASH(0x1abae6c)~0x1ab55ac '2 +0' R R A 1) bind 1 <== '20' (attribs: ) bind 1 <== '20' (size 2/3/0, ptype 4, otype 1) bind 1: CTy=1, STy=VARCHAR, CD=80, Sc=0, VM=2. bind 2 <== 'R' (attribs: ) bind 2 <== R (size 1/2/0, ptype 6, otype 1) bind 2: CTy=1, STy=VARCHAR, CD=80, Sc=0, VM=1. bind 3 <== 'R' (attribs: ) bind 3 <== R (size 1/2/0, ptype 6, otype 1) bind 3: CTy=1, STy=VARCHAR, CD=80, Sc=0, VM=1. bind 4 <== 'A' (attribs: ) bind 4 <== A (size 1/2/0, ptype 6, otype 1) bind 4: CTy=1, STy=VARCHAR, CD=80, Sc=0, VM=1. bind 5 <== '1' (attribs: ) bind 5 <== 1 (size 1/2/0, ptype 6, otype 1) bind 5: CTy=1, STy=VARCHAR, CD=80, Sc=0, VM=1. dbd_st_execute (for sql f31660176 after)... dbd_describe sql 31660176: num_fields=0 dbd_describe skipped (no result cols) (sql f31660176) dbd_st_execute got no rows: resetting ACTIVE, moreResults <- execute= 1 at a.pl line 19 ...

    You have three more variables to play with: version of DBD::MySQL, version of MySQL, version of Perl... That is, of course, if you care... since you got it to work. ;)

    --perlplexer

    <CODE>PS: PostgreSQL++ ;)<CODE>