Cap'n Steve has asked for the wisdom of the Perl Monks concerning the following question:

I just started having some problems with some scripts that use prepared sql statements. The error I get is something like "check the manual that corresponds to your MySQL server version for the right syntax to use near ''0', '18''" when the statement ends with "LIMIT ?, ?".

The solution I found is to add "{'TYPE' => SQL_INTEGER()}" as a third parameter to the bind_param() call. The really weird part is that this only seems to affect placeholders after a LIMIT.

The MySQL server is the same version it always was, any ideas why this is happening?
  • Comment on My DBI suddenly can't handle placeholders in a LIMIT clause.

Replies are listed 'Best First'.
Re: My DBI suddenly can't handle placeholders in a LIMIT clause.
by erroneousBollock (Curate) on Aug 10, 2007 at 06:58 UTC
    Have you recently updated the DBD::mysql module on your system? (Either via CPAN or via package updates on your OS)

    If so, you may wish to read the changelog for DBD::mysql.

    -David

      I didn't, but my host might have and I don't know any way to be sure. A quick check of the DBD::mysql changelog doesn't seem to show anything related.
Re: My DBI suddenly can't handle placeholders in a LIMIT clause.
by clinton (Priest) on Aug 10, 2007 at 08:37 UTC
    I remember a change in DBD::mysql a couple of years ago, where it suddenly became stricter about the type of data being used to fill in the placeholders - a number of scripts which previously worked, suddenly started to fail.

    It was as though the DBD was interpreting "0" as a string rather than as a number.

    As you have found, binding specific column/data types to each placeholder fixes the problem, and, as a bonus, adds a safety check to the data going to your DB.

    Clint

      I believe someone wrote DBD::mysql::AutoTypes do deal with those kinds of issues.

      Not sure if it's necessary any longer.

      -David.

Re: My DBI suddenly can't handle placeholders in a LIMIT clause.
by DrHyde (Prior) on Aug 10, 2007 at 11:43 UTC
    You often need to do things like this with DBD::SQLite too. SQLite only does strings, but if you pass a number to the $sth->execute() method it gets terribly confused. An easier work-around though than explicitly passing the type is to say $sth->execute('' . $number).

    Maybe $sth->execute(0 + $number) will convince DBD::Mysql in your case.

      Actually, doing math with the variable doesn't help. Perl must know it's a number but something in the database driver causes it to forget.
Re: My DBI suddenly can't handle placeholders in a LIMIT clause.
by Cody Pendant (Prior) on Aug 13, 2007 at 01:16 UTC
    Cap'n Steve, are you by any chance using DreamHost?

    I just had the exact same symptoms on a DreamHost website. I've put in a service call to them about it.

    This seems to suggest that DBD::mysql version 2.9 causes this problem, and DreamHost do seem to have made changes to their mysql very recently.



    Nobody says perl looks like line-noise any more
    kids today don't know what line-noise IS ...
      Yes I am, and that's an interesting thread you linked to. I wonder why it was changed, though. Automatically using the appropriate type worked fine, and I don't see why this specifically affects LIMITs.
        I assumed it was just a bug, or unintended feature.

        By the way, here's the rather cryptic DreamHost blog post on mysql 5 days ago: "while upgrading a package..."



        Nobody says perl looks like line-noise any more
        kids today don't know what line-noise IS ...
Re: My DBI suddenly can't handle placeholders in a LIMIT clause.
by Cody Pendant (Prior) on Aug 27, 2007 at 03:19 UTC
    Just to get "closure" in the non-programming sense: Dreamhost eventually wrote back to me to say, yes, they had upgraded the version of the mysql driver. Not only that but they'd upgraded, found that lots of stuff fell over, so they downgraded again, but to a different version than the original one.

    I don't know if I dare put my placeholders back or not!



    Nobody says perl looks like line-noise any more
    kids today don't know what line-noise IS ...
      That reminds me, I actually did find (but can't find again) a mailing list discussion where they mentioned that using placeholders as part of the LIMIT was bad practice (although I have no idea why, or how that applies to DBI interpreting them as strings). For now, I'm just using the bind_param() workaround mentioned earlier because it's just prettier than building the query without placeholders.