我使用PHP脚本将数据从mysql数据库迁移到另一个具有不同模式的mysql数据库。我目前正在处理的实体非常简单。这是用户数据。我的所有数据库表都有utf8_general_ci
排序规则以支持阿拉伯文本。
我可能会收到以下错误:
无法运行查询#14:(1064)您的SQL语法出错; 检查与您的MySQL服务器版本对应的手册 正确的语法在'ايمانمصطفى','1425827057',0,0,1附近使用, '非洲/开罗','',0)'在第1行
这里出乎意料的事情:当我因为错误而在停止之前删除新添加的记录到目标数据库并再次运行我的脚本时,我得到了同样的错误但是又有另一条记录!
在上面提到的错误中,您可能会注意到查询中的阿拉伯名称ايمان مصطفى
缺少两个单引号'
中的一个。但是,我确信我的脚本用单引号括起值,如下所示:
$sqlFormat = "INSERT INTO users (uid, name, pass, theme, signature, created, access, login, status, timezone, language, picture) VALUES ('%s', '%s', '%s', '', '%s', '%s', 0, 0, 1, '%s', '', 0)";
$sql = sprintf($sqlFormat, $user['uid'], $user['name'], $user['pass'], $user['signature'], $user['created'], $user['timezone']);
$res2 = mysqli_query($db2, $sql);
if (!$res2) {
echo "Failed to run query #$i: (" . $db2->errno . ") " . $db2->error;
echo "\n";
echo $sqlInsert;
if ($db2->errno != 1062) {
exit();
}
这是针对传递给查询的INSERT
sql语句的打印输出生成的随机错误的示例:
Failed to run query #4: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'عبد العزيز كحيل', '1425828804', 0, 0, 1, 'Africa/Cairo', '', 0)' at line 1
INSERT INTO users (uid, name, pass, theme, signature, created, access, login, status, timezone, language, picture) VALUES ('149', 'عبد العزيز كحيل', 'U.GCK9X7@$7-w$1@lZQ5HZ=x}M(@a5D}<`Cdod13aJ8O/&&>0%w7jUrKm[bX\', '', 'عبد العزيز كحيل', '1425828804', 0, 0, 1, 'Africa/Cairo', '', 0)
您可能会注意到阿拉伯名称عبد العزيز كحيل
被name
字段的值的两个单引号正确包围,但它缺少signature
字段的尾随单引号。
我的问题是:
答案 0 :(得分:1)
我无法真实地告诉你为什么会发生这种情况,我猜这个语言有一些字符集问题。您的脚本是保存为UTF-8,数据库是UTF-8还是您的连接也是UTF-8?
一种方式(我的最佳选择)是使用PreparedStatements。让数据库完成工作,而不是填写自己的值。由于您已经在使用sprintf,因此您可以轻松了解PreparedStatements的工作原理,因为它们使用类似的语法并且工作方式类似。不同之处在于,您没有直接填写您的值,而是按原样将此查询发送到数据库,然后逐个发送您的值。
看一下mysqli::prepare,这些例子展示了如何用mysqli处理预处理语句。