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

I am working on a script to pull data out of MediaMonkeys SQLite database. When I try:

my sql = qq{SELECT SongTitle, SongPath FROM Songs WHERE (Songs.Artist + LIKE '%'||?||'%' OR Songs.Artist LIKE '%'||?||'%' OR Songs.Artist LI +KE '%'||?||'%' OR Songs.Artist LIKE '%'||?||'%' OR Songs.Artist LIKE +'%'||?||'%' OR Songs.Artist LIKE '%'||?||'%' OR Songs.Artist LIKE '%' +||?||'%') )}; my $dbo = DBI->connect("dbi:SQLite:$mediaMonkeyPath","","") or die("Co +uldn't connect to MediaMonkey - $DBI::errstr\n"); my $sto = $dbo->prepare("$sql") my $results = $sto->execute( @inc_artists ) or die("Failed to Execute +SQL");

I get an error on the prepare statement:

can't install, unknown collation : IUNICODE at C:/strawberry/perl/vendor/lib/DBD/SQLite.pm line 141, <> line 1.

I only get this error on Strawberry Perl on 64 bit Windows 7 (2 different systems). I don't get the error using Strawberry Perl under a Windows 7 32 bit VM, or using Active Perl on 64 bit Windows Vista. I can't haven't tested this code under Linux yet.

I'm looking for any clues what this error means (my Google searches were fruitless), and what might be causing it.

Thanks in advance.

Replies are listed 'Best First'.
Re: Error with DBI and Strawberry Perl under 64 bit W7
by Corion (Patriarch) on Jun 24, 2010 at 21:19 UTC

    Maybe you have different versions of DBD::SQLite installed?

      Maybe, I'll check. Although it seems unlikely since all of these systems were rebuilt within the last 6 months. I don't remember when I installed Perl, and DBD::SQLite, but it's less that 6 months. Thanks for the suggestion.

      EDIT

      OK, you may be on to something here. On the systems where I have the error I am running the last version of DBD::SQLite (ver 1.29). On at least one of the systems where I don't have the error, I am running DBD::SQLite ver 1.25.

      I'm still clueless as to what this error means, and how to correct it.

      EDIT 2:

      So, I rolled back to DBD::SQLite 1.25, and all my code works.

      So thanks to Corion, I worked around the problem, but I still don't understand what that error means, or what was wrong with my code ...

        Same problem here :-)
Re: Error with DBI and Strawberry Perl under 64 bit W7
by roboticus (Chancellor) on Feb 22, 2011 at 13:47 UTC

    Mad_Mac

    I've got nothing to say about your problem (as I have't programmed in Windows 7, nor do I use Strawberry perl). I just have a couple random notes:

    • When you have a repeated clause in your SQL statement, if it can repeat a variable number of times, you can build the clause dynamically.
    • I generally try to keep my embedded SQL stuff looking clean, so I would have added the leading and trailing '%' symbols in the call, rather than in the code. It makes the code a little easier to read (IMHO).
    • You don't need to wrap a variable in quotes to use it.

    So, I would have written it something like this:

    my $SQL = q{SELECT SongTitle, SongPath FROM Songs WHERE }; $SQL .= join('OR', map { '(Songs.Artist LIKE ?)' } @inc_artists); my $DBO = DBI->connect("dbi:SQLite:$mediaMonkeyPath", "", "") or die "Couldn't connect to MediaMonkey - $DBI::errstr\n"; my $STO = $DBI->prepare($SQL); my $results = $STO->execute( map { "\%$_\%" } @inc_artists);

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      roboticus,

      Thanks. Good idea.

      Although, I'd also need to include the || concatenation operators for SQL (I think that syntax is peculiar to SQLite). I could do that in the map function, I guess.

        Mad_Mac:

        Nah, you don't need the concatenation operators. That's why I put the map in there. I think you're getting stuck on making the SQL concatenate the strings together, rather than letting perl do it for you.

        Think of it this way, you get a list of artists to search for:

        my @inc_artists = ( 'Watson', 'Cline', 'Horne' );

        The first chunk of code would generate an SQL statement that looks like:

        SELECT SongTitle, SongPath FROM Songs WHERE (Songs.Artist LIKE ?) OR (Songs.Artist LIKE ?) OR (Songs.Artist LIKE ?)

        The map statement with the execute wraps your artist names with the '%' symbols you want, so they end up look like:

        ( '%Watson%', '%Cline%', '%Horne%' );

        Finally, the execute statement would effectively have a statement like:

        SELECT SongTitle, SongPath FROM Songs WHERE (Songs.Artist LIKE '%Watson%') OR (Songs.Artist LIKE '%Cline%') OR (Songs.Artist LIKE '%Horne%')

        which is what I think you want to feed to SQLite.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.