我正在使用 PHP - PDO 使用 RowVersion 将 SQL Server 表从我们的 ERP 同步到 MariaDB 数据库(托管)。
当我将值保存在本地(办公室)MariaDB 数据库版本 5.5.56 中时,一切正常并且数据存储正确。当我使用 MariaDB 版本 10.0.37 将数据存储在我们的主机中时,rowversion 字段会保存一个不同的值。
我尝试使用 PHP PDO 在办公室 MariaDb 和远程 MariaDb 之间复制数据,而不是从 SQL Server 复制数据,但我遇到了同样的问题。原始 rowversion 值与远程 rowversion 值不同。
为了存储 rowversion 字段,我使用了 VARBINARY(8)。
例子:
ERP SQL SERVER ROW:(id、description、rowversion)。值:1,AMARILLO,0x00000000025DB362 ERP ROW
MariaDb 本地数据库:存储值 1,AMARILLO,00000000025db362 本地 MariaDb 行
MariaDb 远程数据库:存储值:1,AMARILLO,00000000025d3f62 MariaDb 远程行
我不明白为什么远程 MariaDb 会保存不同的值。两个 mariadb 表是相同的,但一个存储一个值,另一个存储不同的值。有任何想法吗?会不会是数据库版本问题?
PHP TEST 代码,在本例中是从本地 MariaDb 到远程 MariaDb:
$sql = "SELECT * FROM colors";
$sth = $this->Db->localdb->query($sql);
$res = $sth->fetchAll(PDO::FETCH_ASSOC);
$sql = "TRUNCATE TABLE colors";
$this->Db->remotedb->exec($sql);
$sql = "INSERT INTO colors (id,des,rowversion) VALUES (?,?,?)";
$sthinsert = $this->Db->remotedb->prepare($sql);
foreach ($res as $line)
{
echo "Inserting color {$line['id']}" . PHP_EOL;
$sthinsert->execute(array(
$line['id'],$line['des'],$line['rowversion']
));
}
桌子:
CREATE TABLE `colors` (
id int NOT NULL,
des varchar(30),
rowversion varbinary(8),
date timestamp NOT NULL DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ENGINE=myisam DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci COMMENT 'Colors';
更新和解决:
阅读这篇文章PHP/PDO/MySQL: inserting into MEDIUMBLOB stores bad data我已经测试过更改远程数据库中的 SET NAMES 后。这解决了问题。
我将此行添加到我的 PHP 程序中:
$this->Db->remotedb->exec("SET NAMES latin1 COLLATE latin1_general_ci");
现在的问题是为什么数据库(MariaDB)以一种方式工作,而另一种方式则以另一种方式工作。
Sqlserver 正在使用 Modern_Spanish_CI_AS 排序规则。
本地 mariadb 正在使用 utf8mb4_unicode_ci,我在 PDO utf8 中设置
远程 mariadb 在 utf8mb4_general_ci 中,我也在为 utf8 设置 PDO。
使用这些排序规则,来自 SqlServer 的数据以不同的方式存储。设置新的排序规则解决了它。如果 PDO 可以使用二进制数据而不需要任何与校对相关的解释,那就更好了。
第二次更新
我找到了一个更好的方法来做到这一点:
我使用 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 创建表
我将 PDO 中的 CHARSET 更改为:
$this->Db->remotedb->exec("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");
有了这个,rowversion 和语言特定的字符被正确存储。
干杯。