我正在Delphi应用程序上开发,该应用程序可以与远程MariaDB数据库通信(通过ADO和ODBC驱动程序(。发现在某些计算机上无法将西里尔字母字符串添加到DB中。错误消息如下:[MySQL][ODBC 8.0(w) Driver][mysqld-5.5.5-10.3.29-MariaDB]Incorrect string value: 'xC2xC2xC8 xF1xE8…' for column <here's target tables and columns name> at row 1
字符集为utf8
,校勘为utf8_bin
。它在我的Windows 10电脑上运行得很好,但在Windows 8和Vista电脑上出现错误。所以,据我所知,问题不在于数据库设置,而在于操作系统。它可以是什么?也许是地区背景或类似的东西?
更新
表:
SHOW CREATE TABLE equip;
CREATE TABLE `equip` (
`eqid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`eqname` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Наименование оборудования',
PRIMARY KEY (`eqid`),
UNIQUE KEY `eqname_UNIQUE` (`eqname`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
连接到DB:
procedure OpenDBConnection;
begin
dmMain.dbConnection.Connected := False;
dmMain.dbConnection.ConnectionString := Format(
'Driver={MySQL ODBC 8.0 Unicode Driver};Port=%s;Server=%s;Database=%s;User=%s;Password=%s;',
[Port, Server, Database, User, Password]);
dmMain.dbConnection.Connected := True;
end;
将数据插入DB:
const
tblEquip = 'equip';
colEquipName = 'eqname';
queryInsertEquipment =
' INSERT INTO ' + tblEquip + '(' +
colEquipName + ') ' +
'VALUES(:' +
colEquipName + '); ';
function TdmMain.AddEquipment(const Equip: TEquipment;
const RefreshEquipmentListDataSet: Boolean): Integer;
begin
Result := 0;
try
cmdTemp.CommandText := queryInsertEquipment;
cmdTemp.Parameters.ParamByName(colEquipName).Value := Equip.Name;
cmdTemp.Execute;
Result := GetLastID;
if RefreshEquipmentListDataSet then
RefreshDataSet(dsetEquipment, colEquipID, Result);
except on E: Exception do
fmMessage.ShowMessage(msgErrorAddEquipment, mtError);
end;
end;
您必须定义客户端和数据库之间通信的编码。如果不这样做,那么数据库会采用一种编码,而客户端可能会采用不同的编码。最有可能的是,较旧的安装默认情况下不使用UTF-8。仅仅因为所有数据库表都是用Unicode字符集和排序规则定义的,这并不意味着写入和读取这些表的数据都是用相同的编码进行通信的。
-
MySQL的
SET NAMES
是一种同时设置多个变量的方便方法。使用像utf8
这样的编码不会转换任何内容——它告诉数据库解释该编码中的所有传入字节(并在为所有结果发送字节时使用该编码( -
PHP的
mysqli_set_charset()
在内部也在做同样的事情,但提供这个函数也是为了了解您对其他方便函数(如mysqli_real_escape_string()
(的选择
在您确保通信实际上以UTF-8进行后,只剩下您的客户端本身:如果您交出DelphiWidestring
,驱动程序会为您进行转换吗?还是必须提供实际的UTF-8编码字节作为查询?这些链接不是为了好玩:这些文件告诉你足够多的事实,可以检查和测试——没有必要质疑它们,也没有必要做出疯狂的假设——这只会让你理解错误。