UnicodeDecodeError в pyodbc при передаче параметров к cursor.execute (), но не при записи параметров непосредственно в строку - PullRequest
0 голосов
/ 25 января 2019

При попытке передать параметр в подготовленный оператор с помощью pyodbc, Python возвращает UnicodeDecodingError.Однако при добавлении параметра непосредственно в подготовленную строку оператора такой ошибки не возникает.

Я работаю в Windows 10 (64-битная версия), используя библиотеку pyodbc в Python 3 и драйвер «Oracle in OraDB12Home1».Получение информации из базы данных работает нормально при добавлении всех параметров непосредственно в строку, содержащую операторы sql.

Вот два примера, которые выдают указанную ошибку

Пример 1

cursor = cnxn.cursor()
sql_statement = "select col1 from ? where col1 is not null;"
params = ("db_name")
cursor.execute(sql_statement,params)

Пример 2

cursor = cnxn.cursor()
sql_statement = "select col1 from db_name where col1 is not ?;"
params = ("null")
cursor.execute(sql_statement,params)

В обоих случаях возникает следующая ошибка:

---------------------------------------------------------------------------

UnicodeDecodeError                        Traceback (most recent call last)

~\AppData\Local\conda\conda\envs\fasttext\lib\encodings\utf_16_le.py in decode(input, errors)

     15 def decode(input, errors='strict'):

---> 16     return codecs.utf_16_le_decode(input, errors, True)

     17

UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 160-161: illegal encoding

Обратите внимание, что при выборе другогобаза данных (например, замена «db-name» на «Different_db_name») не работает, и все равно выдает ту же ошибку.

Ожидаемое поведение

Я ожидаю того жеРезультат, как в следующем примере, который работает без ошибок:

cursor = cnxn.cursor()
sql_statement = "select col1 from db_name where col1 is not null;"
cursor.execute(sql_statement)

Также обратите внимание, что передача различных параметров работает нормально.Например, выполнение следующего кода не вызывает ошибок, хотя единственным отличием от приведенных выше примеров является передаваемый параметр.

cursor = cnxn.cursor()
sql_statement = "select ? from db_name where col1 is not null;"
params = ("col1")
cursor.execute(sql_statement)

1 Ответ

0 голосов
/ 25 января 2019

X is null и X is not null являются предложениями языка SQL - см .: NULL условия .
Есть ключевые слова SQL, ключевое слово NULL в этих пунктах является частью синтаксиса, вы просто не можете передать ключевое слово в качестве параметра.

Поэтому это неверно:

sql_statement = "select col1 from db_name where col1 is not ?"

Вы должны использовать что-то вроде этого:

param = "null"
if param == "null":
    sql_statement = "select col1 from db_name where col1 is null"
else:
    sql_statement = "select col1 from db_name where col1 is not null"

То же самое относится к именам таблиц - их нельзя передавать как переменные связывания.
Я не буду объяснять, почему существует множество ответов на эту тему, например, этот:
динамическая передача имени таблицы и столбца с использованием переменных связывания

Поэтому это неверно:

sql_statement = "select col1 from ? where col1 is not null"

Вы должны использовать это вместо:

param = "db_name"
sql_statement = "select col1 from " + param + " where col1 is not null"
...