为什么mysql在似乎没有时会给我一个语法错误?

时间:2012-02-11 12:04:41

标签: mysql perl

以下代码可运行且工作正常,但如果我将$dbh->do("set names utf8");更改为$dbh->do("set names gbk");,我将收到语法错误:

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;

语法错误如下:

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.

和可疑的行读 'id=\'W5M0MpCehiHzreSzNTczkc9d\'?>\n<x:xmpmeta xmlns:x=\'adobe:ns:meta/\' 与我试图存储到longblob的test.jpg图像文件相关联,因为如果我使用文本编辑器打开图像文件,我可以找到相同的字符串。

如果我更改$ dbh-&gt; do(“set names utf8”),代码也可以工作,这很奇怪;到$ dbh-&gt; do(“set names gb2312”);为什么set name gbk语句给我一个语法错误?有什么明显的东西我做错了吗?

提前致谢:)

我正在运行ActivePerl 5.10.1和MySQL 5.5。

更新

我找到了罪魁祸首!

此行local $/;导致MySQL语法错误。要解决此问题,只需注释掉这一行。

我的Perl脚本以GBK编码,我的数据库表编码也是GBK,但是我还必须在glk中将设置名称添加到perl中的DBI,否则插入表中的GBK字符将无法正确显示GBK环境。

UPDATE2

我以为我已经解决了问题,但问题实际上仍然存在。当我删除本地$ /; line,没有错误消息,但blob字段包含损坏的图像文件。

2 个答案:

答案 0 :(得分:3)

GBK已过时,您不能再使用它了;并且MySQL不支持当前的标准GB 18030。

解决方法:不要set names,并且只处理Perl中的文本编码。将二进制数据(如图像)保持为八位字节。

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
);

(我还没有测试过这段代码。)

答案 1 :(得分:0)

com / users / 183467 / mike

我使用addslashes($ img)函数解决了这个问题。 没有它,img var包含需要用斜杠覆盖的字符,以使它们正确地进入数据库。.否则,似乎这些字符会与您的sql代码混合并被误读为语法错误。

这就是为什么即使在删除外观错误消息后,也无法以正确的方式存储图像。