MariaDB хранит поле varbinary, значение которого отличается от исходного поля, используя PHP PDO - PullRequest
0 голосов
/ 29 декабря 2018

Я использую PHP - PDO для синхронизации таблицы SQL Server с помощью RowVersion из нашей ERP в базу данных MariaDB (хостинг).

Когда я сохраняю значения в локальной (офисной) базе данных MariaDB версии 5.5.56, все идет хорошо, и данные хранятся правильно.Когда я делаю то же самое для хранения данных на нашем хостинге с MariaDB версии 10.0.37, поле rowversion сохраняет другое значение.

Я пытался вместо SQL Server копировать данные между офисом MariaDb и удаленнымMariaDb, используя PHP PDO, и у меня та же проблема.Исходное значение rowversion отличается от удаленного значения rowversion.

Для хранения поля rowversion я использую VARBINARY (8).

Пример:

  • ERPSQL SERVER ROW: (идентификатор, описание, версия строки).Значения: 1, AMARILLO, 0x00000000025DB362 ERP ROW

  • Локальная база данных MariaDb: сохраненные значения 1, AMARILLO, 00000000025db362 Локальная строка MariaDb

  • Удаленная база данных MariaDb: сохраненные значения: 1, AMARILLO, 00000000025d3f62 Удаленная строка MariaDb

Не понимаю, почему удаленный MariaDbсохраняет другое значение.Обе таблицы mariadb идентичны, но одна хранит одно значение, а другая - другое значение.Есть идеи?это может быть проблема с версией базы данных?

PHP TEST code, в данном случае с локального 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 для utf8mb4_general_ci, и я такжедля utf8.

При этих сопоставлениях данные, поступающие с SqlServer, хранились иначе.Установка нового сопоставления решила это.Было бы лучше, если бы PDO мог использовать двоичные данные без какой-либо интерпретации для сопоставления.

ВТОРОЕ ОБНОВЛЕНИЕ

Я нашел лучший способ сделать это:

  • Я создаю таблицу с CHARSET =utf8mb4 COLLATE = utf8mb4_unicode_ci

  • Я изменяю CHARSET в PDO на:

$this->Db->remotedb->exec("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");

При этом, перевод строки иЯсные специфические символы сохраняются правильно.

Приветствия.

1 Ответ

0 голосов
/ 29 декабря 2018

PDO пытается преобразовать двоичное значение в строку, используя указанную кодировку UTF-8.B3 не является допустимой кодовой точкой и поэтому заменяется на ? - при кодировании обратно из строки в двоичный файл вы получите 3F в качестве значения для символа замены ?.

.PDO от выполнения двоичного преобразования в строку, см. Этот пост SO:

сохранить изображение в базе данных mssql как varbinary (max) без преобразования

...