mariadb使用phppdo存储varbinary字段,其值与原始字段不同

at0kjp5o  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(452)

我正在使用php-pdo将使用rowversion的sql server表从我们的erp同步到一个mariadb数据库(宿主)。
当我将值保存在本地(office)mariadb数据库版本5.5.56中时,一切正常,数据存储正确。当我使用mariadb版本10.0.37在宿主中存储数据时,rowversion字段保存一个不同的值。
我尝试过,而不是从sql server,使用php pdo在office mariadb和远程mariadb之间复制数据,我也遇到了同样的问题。原始rowversion值与远程rowversion值不同。
为了存储rowversion字段,我使用varbinary(8)。
例子:
erp sql server行:(id,description,rowversion)。值:1,amarillo,0x00000000025db362 erp行
mariadb本地数据库:存储值1,amarillo,00000000025db362本地mariadb行
mariadb远程数据库:存储值:1,amarillo,00000000025d3f62 mariadb远程行
我不明白为什么远程mariadb保存不同的值。两个mariadb表是相同的,但是一个表存储一个值,而另一个表存储不同的值。有什么想法吗?可能是数据库版本问题吗?
php测试代码,在本例中,从本地mariadb到远程mariadb:

  1. $sql = "SELECT * FROM colors";
  2. $sth = $this->Db->localdb->query($sql);
  3. $res = $sth->fetchAll(PDO::FETCH_ASSOC);
  4. $sql = "TRUNCATE TABLE colors";
  5. $this->Db->remotedb->exec($sql);
  6. $sql = "INSERT INTO colors (id,des,rowversion) VALUES (?,?,?)";
  7. $sthinsert = $this->Db->remotedb->prepare($sql);
  8. foreach ($res as $line)
  9. {
  10. echo "Inserting color {$line['id']}" . PHP_EOL;
  11. $sthinsert->execute(array(
  12. $line['id'],$line['des'],$line['rowversion']
  13. ));
  14. }

表格:

  1. CREATE TABLE `colors` (
  2. id int NOT NULL,
  3. des varchar(30),
  4. rowversion varbinary(8),
  5. date timestamp NOT NULL DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP,
  6. PRIMARY KEY (id)
  7. ) ENGINE=myisam DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci COMMENT 'Colors';

更新并解决:
在阅读了这篇文章php/pdo/mysql:inserting into mediumblob存储了坏数据之后,我测试了如何更改远程数据库中的集合名称。解决了问题。
我在php程序中添加了以下行:

  1. $this->Db->remotedb->exec("SET NAMES latin1 COLLATE latin1_general_ci");

现在的问题是,为什么数据库(mariadb)以一种方式工作,而第二种方式工作。
sqlserver正在使用modern\u spanish\u ci\u作为排序规则。
本地mariadb正在使用utf8mb4\u unicode\u ci,我设置了pdo utf8
远程mariadb在utf8mb4\u general\u ci中,我还为utf8设置了pdo。
通过这些排序规则,来自sqlserver的数据存储方式不同。设置新的排序规则解决了这个问题。如果pdo可以使用二进制数据,而不需要任何与排序相关的解释,那就更好了。
第二次更新
我找到了更好的方法:
我用charset=utf8mb4 collate=utf8mb4\u unicode\u ci创建表
我将pdo中的字符集更改为: $this->Db->remotedb->exec("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"); 这样,rowversion和languague特定的字符就可以正确存储。
干杯。

l7wslrjt

l7wslrjt1#

pdo尝试使用指定的utf-8编码将二进制值转换为字符串。 B3 不是有效的代码点,因此被替换为 ? -当从字符串编码回二进制时,您将得到 3F 作为替换字符的值 ? .
要防止pdo进行二进制到字符串的转换,请参阅以下内容:
将mssql数据库中的图像保存为varbinary(max),无需转换

相关问题