Как вставить байтовые строки в SAP HANA

Я пытаюсь вставить две строки байтов в таблицу SAP HANA со столбцами VARBINARY, но получаю синтаксическую ошибку.

Мои две строки, которые выглядят так:

STRING1 = b'G\xa2ac\xa0av\xf6'  
type(STRING1) == <class 'bytes'>
STRING2 = b'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6' 
type(STRING2) == <class 'bytes'>

Мой запрос на вставку значений выглядит так:

INSERT INTO testTable VALUES(
CAST(b'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6' AS VARBINARY),
CAST(b'G\xa2ac\xa0av\xf6' AS VARBINARY));

Я также попытался сделать запрос, как следует из документации:

INSERT INTO testTable VALUES(
CAST(x'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6' AS VARBINARY),
CAST(x'G\xa2ac\xa0av\xf6' AS VARBINARY));

Так же как:

INSERT INTO testTable VALUES(
b'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6',
b'G\xa2ac\xa0av\xf6');

Но все это дает мне некоторую синтаксическую ошибку. Любая помощь будет принята с благодарностью. Спасибо!

2 ответа

Проблема здесь заключается в вашем STRING1 значение (b'G\xa2ac\xa0av\xf6'). Это недопустимая шестнадцатеричная строка, которая может представлять двоичное значение в SAP HANA. Вот почему любое приведение типов здесь не удастся. Вместо этого кажется, что это на самом деле строка, и некоторые символы представлены шестнадцатеричными значениями (возможно, кодовые точки UNICODE?).
По крайней мере, это то, что я делаю из \x escape-последовательность в строке.

Таким образом, вы можете делать разные вещи сейчас.

  1. Вы можете сохранить строку как есть с escape-последовательностями вVARBINARY колонка. Для этого вы можете использоватьto_binary('G\xa2ac\xa0av\xf6') в заявлении вставки.
  2. Вы можете преобразовать эту строку в допустимую строку UNICODE в коде приложения и сохранить данные в NVARCHAR столбец вместо.

Насколько я знаю, HANA не понимает байт-кодирование, как python, поэтому я думаю, что есть путаница, если вы используете это представление в консоли sql. Так, в python при печати b'G\xa2ac\xa0av\xf6'байт, который не представлен в ascii (ваша локальная кодировка?), Имеет префикс \x.

Если вы хотите сделать это, вы можете сначала преобразовать это в шестнадцатеричное представление в python

>>> import binascii
>>> binascii.hexlify(b'\xa2ac\xa0av\xf6')
b'47a26163a06176f6'

Это даст вам единообразное представление вашего байтового массива в шестнадцатеричном виде, которое вы теперь можете использовать в своей консоли SQL (как HANA Studio и тому подобное):

INSERT INTO TestTable VALUES(x'47a26163a06176f6');
-- OR
INSERT INTO TestTable VALUES(HEXTOBIN('47a26163a06176f6'));

Обратите внимание, что префикс b меняется на x в первом случае, чтобы указать HANA, что он должен рассматривать это как двоичные данные в шестнадцатеричном представлении.

Чтобы вставить значение из Python 2 как подготовленный оператор:

>>> cursor.execute("INSERT INTO TestTable Values(?)", \
        parameters=[binascii.hexlify(b'G\xa2ac\xa0av\xf6')])

PyHDB, кажется, ожидает, что строка справится правильно, но в Python 3 hexlify выдаст байтовый массив, поэтому вам нужно снова превратить результат в строку

>>> param = str(binascii.hexlify(b'G\xa2ac\xa0av\xf6'), 'ascii')
>>> cursor.execute("INSERT INTO TestTable Values(?)", parameters=[param])

Я предполагаю, что это может считаться ошибкой в ​​PyHDB или, по крайней мере, несоответствием. Для полноты картины в клиенте dbapi SAP есть класс Binary для обертывания байтовых массивов для этой цели.

Теперь запросите это с вашим клиентом

>>> import pyhdb
>>> con = pyhdb.connect(....)
>>> cursor = con.cursor()
>>> cursor.execute('SELECT * FROM TestTable')
>>> cursor.fetchall()
[(b'G\xa2ac\xa0av\xf6',)]

Подводя итог, можно сказать, что b'G\xa2ac\xa0av\xf6'не является представлением, которое HANA понимает как таковое при использовании его в выражении SQL. Нам нужно найти общий язык, для этого мы преобразовали байтовый массив в шестнадцатеричное представление (hexlify) и сказал HANA обработать его как таковой (x-prefix / HEXTOBIN).

Как Ларс Бр. упомянуто, если это действительно литералы юникода, вы можете рассмотреть NVARCHAR как тип данных.

Другие вопросы по тегам