python - 将参数传递给 cursor.execute() 时在 pyodbc 中出现 UnicodeDecodeError,但在将参数直接写入字符串时却不会

标签 python sql windows oracle pyodbc

当尝试使用 pyodbc 将参数传递给准备好的语句时,Python 返回 UnicodeDecodingError。但是直接在prepared statement string中添加参数时,就没有这个错误了。

我在 Windows 10(64 位)上工作,使用 Python 3 中的 pyodbc 库和“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)

最佳答案

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"

这同样适用于表名——它们不能作为绑定(bind)变量传递。
我不会解释为什么,关于这个问题有很多答案,例如这个:
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"

关于python - 将参数传递给 cursor.execute() 时在 pyodbc 中出现 UnicodeDecodeError,但在将参数直接写入字符串时却不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54369041/

相关文章:

sql - 将选择转换为更新

sql - 尝试从日期中提取月份时出现错误

sql - 在 PostgreSQL 中创建嵌套 json blob

c++注册表没有获得第二个值

windows - 使用命令行打印特定的 PDF 页面

python - numpy 除法与 RuntimeWarning : invalid value encountered in double_scalars

python - tkinter 中的非顶级 opengl 小部件

c++ - 在多线程程序中同步嵌入式Python

python - 保留满足条件的行和相邻行

c - 使用 getenv 在 C 中构建路径