将参数传递给cursor.execute()时,pyodbc中的UnicodeDecodeError,但不直接将参数写入字符串时

时间:2019-01-25 16:15:22

标签: python sql windows oracle pyodbc

当尝试使用pyodbc将参数传递给准备好的语句时,Python返回UnicodeDecodingError。但是,将参数直接添加到准备好的语句字符串时,不会出现此类错误。

我在Windows 10(64位)上使用Python 3中的pyodbc库并使用“ OraDB12Home1中的Oracle”驱动程序。将所有参数直接添加到包含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)

此外,请注意,传递 different 参数可以正常工作。例如,即使与上面提供的示例的唯一区别是传递的参数,以下代码的执行也不会引发错误。

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

1 个答案:

答案 0 :(得分:0)

X is nullX is not null是SQL语言的子句-请参见:NULL conditions
这些子句中有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"

这同样适用于表名-它们不能作为绑定变量传递。
我不会解释为什么,在这个问题上有很多答案,例如这个答案:
passing table and column name dynamically using bind variables

因此,这是不正确的:

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

您必须改用它:

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