我正在尝试将两个字节字符串插入带有 VARBINARY 列的 HANA 表中,但我不断收到语法错误,例如
SAP DBTech JDBC: [257]: sql 语法错误: "G\xa2ac\xa0av\xf6" 附近的语法不正确: 第 1 行 col 98 (在 pos 98(
我的两个字节字符串如下所示:
STRING1 = b'Gxa2acxa0avxf6'
type(STRING1) == <class 'bytes'>
STRING2 = b'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6'
type(STRING2) == <class 'bytes'>
我插入值的查询如下所示:
INSERT INTO testTable VALUES(
CAST(b'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6' AS VARBINARY),
CAST(b'Gxa2acxa0avxf6' AS VARBINARY));
我还尝试查询文档的建议:
INSERT INTO testTable VALUES(
CAST(x'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6' AS VARBINARY),
CAST(x'Gxa2acxa0avxf6' AS VARBINARY));
以及:
INSERT INTO testTable VALUES(
b'708ca7fbb701799bb387f2e50deaca402e8502abe229f705693d2d4f350e1ad6',
b'Gxa2acxa0avxf6');
但所有这些都给了我一些语法错误。任何帮助将不胜感激。谢谢!
这里的问题在于您的STRING1
值(b'Gxa2acxa0avxf6'
(。 它不是有效的十六进制字符串,可以表示 SAP HANA 中的二进制值。这就是为什么任何类型的转换都会在这里失败的原因。 相反,它似乎实际上是一个字符串,并且某些字符表示十六进制值(也许是UNICODE代码点?
至少我是这样对字符串中x
escpace序列的看法。
所以,你现在可以做不同的事情。
- 您可以按原样存储字符串,转义序列存储在
VARBINARY
列。为此,您可以使用to_binary('Gxa2acxa0avxf6')
插入语句中。 - 您可以在应用程序代码中将此字符串转换为有效的 UNICODE 字符串,并将数据存储在
NVARCHAR
列中。
据我所知,HANA 不像 python 那样理解字节编码,所以我认为如果您在 sql 控制台中使用该表示形式,就会混淆。因此,在python中,当打印b'G\xa2ac\xa0av\xf6'时,在ascii(您的本地编码?(中不可呈现的字节以\x为前缀。
如果你想这样做,你可能首先想把它转换为python中的十六进制表示
>>> import binascii
>>> binascii.hexlify(b'xa2acxa0avxf6')
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'Gxa2acxa0avxf6')])
PyHDB 似乎希望字符串能够正确处理,但在 Python 3 中,hexlify
会产生一个字节数组,因此您需要再次将结果转换为字符串
>>> param = str(binascii.hexlify(b'Gxa2acxa0avxf6'), 'ascii')
>>> cursor.execute("INSERT INTO TestTable Values(?)", parameters=[param])
我想这可以被认为是 PyHDB 中的一个错误,或者至少是不一致的。为了完整起见,在SAP的dbapi客户端中,有一个二进制类来包装字节数组。
现在向您的客户查询
>>> import pyhdb
>>> con = pyhdb.connect(....)
>>> cursor = con.cursor()
>>> cursor.execute('SELECT * FROM TestTable')
>>> cursor.fetchall()
[(b'Gxa2acxa0avxf6',)]
总结一下:b'G\xa2ac\xa0av\xf6' 不是 HANA 在 SQL 语句中使用它时所理解的表示形式。我们需要找到一个共同点,为此我们将字节数组转换为十六进制表示(hexlify
(,并告诉HANA这样处理它(x前缀/HEXTOBIN(。
正如 Lars Br. 所提到的,如果这些确实是 unicode 文字,你可能会 想要将NVARCHAR视为数据类型。