В чем разница между преобразованием в hex на стороне клиента и использованием rawtohex?
Вопрос
У меня есть таблица, которая создана следующим образом:
CREATE TABLE bin_test
(id INTEGER PRIMARY KEY, b BLOB)
Использование Python и cx_Oracle, если я это сделаю:
value = "\xff\x00\xff\x00" #The string represented in hex by ff00ff00
self.connection.execute("INSERT INTO bin_test (b) VALUES (rawtohex(?))",
(value,))
self.connection.execute("SELECT b FROM bin_test")
Я в итоге получаю шестнадцатеричное значение a000a000
, что неверно! Однако, если я сделаю это:
import binascii
value = "\xff\x00\xff\x00"
self.connection.execute("INSERT INTO bin_test (b) VALUES (?)",
(binascii.hexlify(value,)))
self.connection.execute("SELECT b FROM bin_test")
Я получаю правильный результат. У меня есть система преобразования типов, но описать ее здесь довольно сложно. Таким образом, может ли кто-нибудь указать мне правильное направление относительно того, что я делаю что-то не так на уровне SQL или что-то странное происходит с моими преобразованиями?
Решение
rawtohex () предназначен для преобразования типов данных Oracles RAW в шестнадцатеричные строки. Возможно, вы запутаетесь, передав строку, даже если строка содержит двоичные данные. В этом случае, поскольку Oracle ожидает строку из шестнадцатеричных символов, передайте ему строку из шестнадцатеричных символов.
Другие советы
RAWTOHEX
в Oracle
нечувствителен к порядку битов, в то время как на вашем компьютере он, конечно, чувствителен.
Также обратите внимание, что аргумент RAWTOHEX ()
может быть неявно преобразован в VARCHAR2
вашей библиотекой (то есть передан как SQLT_STR
), который делает его также чувствительным к кодированию и сопоставлению.
Обычно я устанавливаю правильный тип привязок переменных, особенно когда пытаюсь передать Oracle тип данных RAW в запрос.
например что-то вроде:
self.connection.setinputsizes(cx_Oracle.BINARY)
self.connection.execute(
"INSERT INTO bin_test (b) VALUES (rawtohex(?))",
(value,)
)