Почему Delphi IBX TWideMemoField преобразует порядок байтов в строку UTF8 и как этого избежать?

Я использую Delphi 2009 с IBX в базе данных Firebird 3 (у меня нет выбора, чтобы выбрать другие технологии, я должен адаптироваться к ситуации). У меня есть следующие определения:

BLOB-поле Firebird определяется как:

BLOB SUB_TYPE 0 SEGMENT SIZE 80

TWideMemoField определяется как:

object MainQryNOTES: TWideMemoField
  FieldName = 'NOTES'
  Origin = 'INVOICES.NOTES'
  ProviderFlags = [pfInUpdate]
  BlobType = ftWideMemo
end

Тестовая строка - «Цель по инфляции,%», и ее можно прочитать из поля BLOB в программе IBExpert как:

26 04 35 04 3B 04 4C 04 20 00 3F 04 3E 04 20 00
38 04 3D 04 44 04 3B 04 4F 04 46 04 38 04 38 04
2C 00 20 00 25 00

Странно то, что Delphi меняет порядок байтов, например кириллический символ Ц имеет представление HEX UTF8 как 04 26, но хранится в базе данных как 26 04, и аналогичная ситуация точно с другими символами (это можно проверить с помощью таблиц https://www.w3schools.com/charsets/ref_utf_basic_latin.asp и https://www.w3schools.com/charsets/ref_utf_cyrillic.asp). В моем случае у меня только 2-байтовые символы, но я предполагаю, что аналогичная ситуация будет и с 3- и 4-байтовыми символами UTF8.

Итак - как я могу настроить TWideMemoField, чтобы он не преобразовывал байтовый порядок строк UTF8?


person TomR    schedule 03.09.2018    source источник
comment
Почему вы задаете (практически) тот же вопрос снова, вместо того, чтобы редактировать оригинал? Ссылка: stackoverflow.com/q/52138881/2292722   -  person Tom Brunberg    schedule 03.09.2018
comment
В этом вопросе я попытался понять, как настроить сохранение из TWideMemoField в базу данных в формате UTF8, и в этом вопросе я попытаюсь понять, как я могу преобразовать UTF16LE в UTF8 в PHP.   -  person TomR    schedule 03.09.2018
comment
попробуйте форум sql.ru, может там были люди, которые встречались. Также, возможно, вы сможете найти IBX новее, чем d2009 из коробки   -  person Arioch 'The    schedule 03.09.2018
comment
Это ваше поле BLOB двоичное, а не текстовое, поэтому мне интересно, попытается ли Firebird его преобразовать. Во всяком случае, вы не указали ни кодировку / сопоставление поля blob, ни кодировку соединения, которую вы настроили. По подтипам BLOB: firebirdsql.org файл / документация / reference_manuals /   -  person Arioch 'The    schedule 03.09.2018


Ответы (1)


Ваш текст не закодирован как UTF8, он закодирован как UTF16. Символ Ц - это U + 0426. И по соглашению 16-битная кодовая единица сохраняется в порядке байтов с прямым порядком байтов, $ 26 $ 04.

Другими словами, все работает так, как ожидалось и как задумано, и я не вижу необходимости в том, чтобы вы пытались что-либо исправить, потому что ничего не сломано.

person David Heffernan    schedule 03.09.2018
comment
Причина для исправления этого заключается в том, что сам Firebird не поддерживает UTF-16, что означает, что вам нужно обрабатывать его как двоичные данные вместо того, чтобы иметь возможность обрабатывать контент в базе данных как текст (то есть: вы не можете правильно использовать некоторые встроенные функции базы данных и операторы для обработки строк). - person Mark Rotteveel; 03.09.2018
comment
@MarkRotteveel Итак, вы говорите, что проблема в том, что используется UTF-16, а не порядок байтов? Что делать дальше - убедиться, что используется UTF-8? - person David Heffernan; 03.09.2018
comment
Только OP может быть уверен в этом, но я бы сказал, что да, тот факт, что UTF-16 сохраняется в базе данных вообще, является потенциальной проблемой, и OP может захотеть исправить это и обеспечить вместо этого сохранение UTF-8. - person Mark Rotteveel; 03.09.2018
comment
@MarkRotteveel, который потребовал бы от него изменения типа поля на лету, что может быть сложно, если зависимости - person Arioch 'The; 04.09.2018