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

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

我正在使用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:

$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存储了坏数据之后,我测试了如何更改远程数据库中的集合名称。解决了问题。
我在php程序中添加了以下行:

$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),无需转换

相关问题