2012-02-11 6 views
1

次のコードは実行可能であると正常に動作しますが、私は$dbh->do("set names gbk");$dbh->do("set names utf8");を変更した場合、私は構文エラーを受け取ります:なぜ、mysqlは何もないと思われるときに構文エラーを表示しますか?

DBD::mysql::st execute failed: You have an error in your SQL syntax; check the m 
anual that corresponds to your MySQL server version for the right syntax to use 
near 'id=\'W5M0MpCehiHzreSzNTczkc9d\'?>\n<x:xmpmeta xmlns:x=\'adobe:ns:meta/\' x 
:xmptk' at line 1 at D:\sqltest.pl line 22. 
DBD::mysql::st execute failed: You have an error in your SQL syntax; check the m 
anual that corresponds to your MySQL server version for the right syntax to use 
near 'id=\'W5M0MpCehiHzreSzNTczkc9d\'?>\n<x:xmpmeta xmlns:x=\'adobe:ns:meta/\' x 
:xmptk' at line 1 at D:\sqltest.pl line 22. 

、不審な行を次のように

use strict; 
use warnings; 
use DBD::mysql; 

my $dbh = DBI->connect("DBI:mysql:database=test;host=localhost","root","password"); 
$dbh->do("set names utf8"); 

open my $jpg, '<', 'test.jpg' or die "$!"; 
binmode $jpg; 
my $image = do{local $/; <$jpg>}; 
close $jpg; 

my $sql = "INSERT INTO student VALUES (?, ?)"; 

my $sth = $dbh->prepare($sql); 
$sth->bind_param(1, 'Yang Liu'); 
$sth->bind_param(2, $image); 
$sth->execute(); 
$sth->finish; 
exit; 

構文エラーが読み込みread 'id=\'W5M0MpCehiHzreSzNTczkc9d\'?>\n<x:xmpmeta xmlns:x=\'adobe:ns:meta/\' は、テキストエディタを使用して画像ファイルを開くと、同じ文字列を見つけることができるので、私がlongblobに保存しようとしているtest.jpg画像ファイルに関連付けられています。

$ dbh-> do( "set names utf8");を変更するとコードが動作するのは変です。 〜$ dbh-> do( "set names gb2312");なぜ、set names gbk文が私に構文エラーを与えるのですか?私が間違っていることが明らかなことはありますか?事前に

感謝:)

私はActivePerlは5.10.1とMySQL 5.5を実行していますよ。

UPDATE

私は犯人を見つけました!

この行local $/;は、MySQL構文エラーの原因です。問題を解決するには、この行をコメントアウトしてください。

私のPerlスクリプトはGBKでエンコードされていますが、私のデータベーステーブルのエンコーディングもGBKですが、DBLにgbkにset名を追加する必要があります。そうしないと、テーブルに挿入されたGBK文字は正しく表示されませんGBK環境で実行します。

アップデート2

私は問題を修正していたが、問題はまだそこに実際にあると思いました。ローカル$ /を削除するとエラーメッセージは表示されませんが、blobフィールドには破損したイメージファイルが含まれています。

+0

どのようなタイプのあなたは画像を保存するテーブルの2番目の列のですか?異なるエンコーディングを使用して異なるエラーが発生するので、イメージバイナリデータを文字列に変換しようとしているように見え、すべてのバイトの組み合わせが有効なUTF-8を生成するとは限りません。 –

+0

テーブルは、create table student(name varchar(20)、pic longblob)を使用して作成されます。私が示すコードはエラーメッセージを正確に生成します。それには2つの "DBD :: mysql :: st execute failed"エラーが含まれています。画像バイナリデータが文字列として扱われているように見えます。 – Mike

+0

phpは自分では使用しませんが、クエリがバイナリを文字列に変換しようとしているかのように見えます。 bind_paramで型を指定しようとしましたか? bind_param(2、$ image、SQL_LONGBLOB)のようなもの –

答えて

3

GBKは古くなっていますので、もう使用しないでください。ないset namesを行う、とだけPerlでテキストのエンコーディングを扱う:とMySQLは現在の標準GB 18030.

回避策をサポートしていません。イメージなどのバイナリデータをオクテットとして保持する。

use utf8; 
use Encode qw(encode); 
use Encode::HanExtra qw(); 
⋮ 
my $name = encode('GB18030', '刘阳', Encode::FB_CROAK | Encode::LEAVE_SRC); 
$dbh->do(
    'INSERT INTO student VALUES (?, ?)', 
    {}, 
    $name, $image 
); 

(私はこのコードをテストしていません。)

+0

GB18030に関する情報は@daximに感謝します。最新の投稿をご覧ください。私は、MySQLの構文エラーを引き起こした原因を見つけました。そして私はPerlでのテキストのエンコーディングしか扱うことができません。セット名をGBIステートメントにDBIに追加しないと、GBKエンコードテーブルに挿入されたGBKエンコード文字がGBK環境で正しく表示されません。 – Mike

関連する問題