I can't test on your exact setup, but the versions that I have probably don't not differ from yours in any relevant detail:
mysql -- 5.0.51b DBI -- 1.52 DBD::mysql -- 4.007
Now, I'll confess that I don't have what qualifies as a deep understanding of how this all works, but I can at least report some test results, which include at least one test condition that appears to work.

But first, I'd like to point out that using accented characters in literal (quoted) strings in your perl script could be one source of trouble -- if you're going to do that, it's good to check it by printing the string to a utf8-mode file handle, or just looking at it with Data::Dumper, to make sure your text editor is saving it (and perl is seeing it) as utf8 data.

That said, here is a little test script that works for me in the setup described above. This assumes that your mysql server still has a "test" database where you can create tables and do stuff as an "anonymous" user. The comments with "fn. #" refer to footnotes that follow. Try this as posted, and if the output ends with "that's bad", then something is probably wrong with your DBI and/or DBD::mysql installation.

#!/usr/bin/perl use strict; use warnings; use DBI; use Encode; binmode STDOUT, ":utf8"; #my $DSN = "DBI:mysql:database=test;host=localhost;mysql_enable_utf8=1 +"; # fn.1 my $DSN = "DBI:mysql:database=test;host=localhost"; my $dbh = DBI->connect( $DSN, "", "" ); my @cols = qw/country city pronunciation/; my $create_table = "create table test_utf8 (". join( ',', map { "$_ varchar(50)" } @cols ) . ")"; $dbh->do( "drop table if exists test_utf8" ); $dbh->do( "$create_table default character set=utf8" ); $dbh->do( "set names utf8" ); # fn.2 my @src_data = ( "Germany", "K\xf6ln", "k\x{0153}ln" ); print "Sending to db: @src_data\n"; #my @tst_data = @src_data; # fn.3 my @tst_data = map { encode( 'utf8', $_ ) } @src_data; my $sth = $dbh->prepare( "insert into test_utf8 (". join( ',', @cols ). ") values (?,?,?)" ); $sth->execute( @tst_data ); my ( @db_data ) = $dbh->selectrow_array( "select ".join( ',', @cols ). " from test_utf8" ); $_ = decode( 'utf8', $_ ) for ( @db_data ); # fn.4 print "Fetch from db: @db_data\n"; my $diff = 0; for ( 0 .. $#db_data ) { $diff++ if ( $db_data[$_] ne $src_data[$_] ); } print "So that's bad\n" if $diff;
Footnotes:

  1. With recent versions of DBD::mysql, you can try configuring the connection with "enable_utf8" turned on, but this is reported to be "experimental", and in any case seems to have no bearing on the behavior for the present test.

  2. The "set names utf8" is a more traditional method for making sure that mysql understands that you want to use utf8 data for tables, but again, it seems to be somewhat peripheral (not mandatory) for the case at hand. (But it does have an impact on internal storage: without this, putting wide characters into utf8 fields will cause any two-byte utf8 character to take up four bytes in the mysql table file -- not good.)

  3. There's a difference in behavior between "Latin1" characters (\x80-\xFF) vs. higher-order unicode characters (\x100 and above); if you uncomment the "fn.3" line and comment out the line after it, you'll see the difference.

  4. This decoding of stuff returned from mysql is necessary, regardless of "set names utf8" or "enable_utf8" or table/column definitions or whatever.

You can play with variations as you like, but the particular arrangement shown should work as-is, and should be a good-enough template to work from. Good luck.

UPDATE: I just noticed that some of this same ground was covered in the first thread you ever posted here at the Monastery: utf8 characters in tr/// or s///. Not only did you forget what we told you back then, but I also forgot what ikegami taught me: you can use utf8::decode( $string ) instead of the slightly more cumbersome $string = Encode::decode( 'utf8', $string ) -- but the latter offers a handy third parameter (for trapping bad data), and is not considered "experimental".


In reply to Re: UTF8 execute() parameters (DBI) by graff
in thread UTF8 execute() parameters (DBI) by MattLG

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.