繁体   English   中英

MariaDB使用PHP PDO以与原始字段不同的值存储varbinary字段

[英]MariaDB stores varbinary field with different value from the original field using PHP PDO

我正在使用PHP-PDO将使用RowVersion的SQL Server表从我们的ERP同步到MariaDB数据库(托管)。

当我将值保存在本地(办公室)MariaDB数据库版本5.5.56中时,一切正常,数据已正确存储。 当我执行相同的操作以将数据存储在MariaDB 10.0.37版中的主机中时,rowversion字段将保存不同的值。

我尝试使用PHP PDO,而不是从SQL Server,在办公室MariaDb和远程MariaDb之间复制数据,但我遇到了同样的问题。 原始rowversion值与远程rowversion值不同。

为了存储行版本字段,我正在使用VARBINARY(8)。

例:

  • ERP SQL SERVER ROW:(ID,描述,行版本)。 值: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:插入MEDIUMBLOB中存储了错误的数据,我已经测试过要更改远程数据库中的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和languague特定的字符。

干杯。

PDO尝试使用指定的UTF-8编码将二进制值转换为字符串。 B3不是有效的代码点,因此被替换为? -从字符串编码为二进制编码时,然后获得3F作为替换字符的值?

为了防止PDO进行二进制到字符串的转换,请参见以下SO帖子:

将图像保存在mssql数据库中为varbinary(max),无需进行转换

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM