in reply to UTF8 execute() parameters (DBI)
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.mysql -- 5.0.51b DBI -- 1.52 DBD::mysql -- 4.007
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.
Footnotes:#!/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;
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".
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: UTF8 execute() parameters (DBI)
by MattLG (Beadle) on Apr 21, 2009 at 09:01 UTC | |
by MattLG (Beadle) on Apr 21, 2009 at 10:11 UTC | |
|
Re^2: UTF8 execute() parameters (DBI)
by Anonymous Monk on Apr 21, 2009 at 09:39 UTC |