传入 Python 列表时的非法变量名称/编号

Posted

技术标签:

【中文标题】传入 Python 列表时的非法变量名称/编号【英文标题】:Illegal Variable Name/Number when Passing in Python List 【发布时间】:2022-01-12 15:53:26 【问题描述】:

我正在尝试通过 Python 在列表上运行 SQL 语句。 通过传入一个列表,在这种情况下是日期。因为我想运行多个 SELECT SQL 查询并返回它们。 我通过传入整数对此进行了测试,但是当尝试传入日期时,我收到 ORA-01036 错误。非法变量名称/编号。我正在使用 Oracle 数据库。

cursor = connection.cursor()
date = ["'01-DEC-21'", "'02-DEC-21'"]

sql = "select * from table1 where datestamp = :date"

for item in date:
    cursor.execute(sql,id=item)
    res=cursor.fetchall()
    print(res)

有什么建议可以运行吗?

【问题讨论】:

用IN代替=,=代表一个值,IN代表列表 @AhmedSunny 感谢您提供此信息。它是一个更大的表,有时使用 IN 解析比一次运行一个需要更长的时间 阅读 cx_Oracle 文档Binding Multiple Values to a SQL WHERE IN Clause,其中有一些通用解决方案。 【参考方案1】:

您不能命名绑定变量date,这是一个非法名称。此外,cursor.execute 中的命名变量应与绑定变量名称匹配。尝试类似:

sql = "select * from table1 where datestamp = :date_input"

for item in date:
  cursor.execute(sql,date_input=item)
  res=cursor.fetchall()
  print(res)

【讨论】:

【参考方案2】:

对您的方法的一些建议和警告:

不应该依赖你的默认NLS日期设置,同时将String(例如"'01-DEC-21'")绑定到DATE列。 (您可能还需要重新引用其中一个引号)。

如果您可以在一个查询中获取数据(使用IN 列表),您应该省略在循环中获取数据

使用准备好的语句

示例

date = ['01-DEC-21', '02-DEC-21']

这会为您的输入列表生成使用绑定变量的查询

in_list = ','.join([f" TO_DATE(:dind,'DD-MON-RR','NLS_DATE_LANGUAGE = American')" for ind, d in enumerate(date)])

sql_query = "select * from table1 where datestamp in ( " + in_list + " )"

sql_query 生成的是

select * from table1 where datestamp in 
(  TO_DATE(:d0,'DD-MON-RR','NLS_DATE_LANGUAGE = American'), TO_DATE(:d1,'DD-MON-RR','NLS_DATE_LANGUAGE = American') )

请注意,INlist 为输入列表的每个成员都包含一个绑定变量。

还要注意to_date 的使用,带有显式掩码并修复语言以避免月份缩写的解释问题。 (例如 ORA-01843: not a valid month

现在您可以使用查询一次性获取数据

cur.prepare(sql_query)
cur.execute(None, date)
res = cur.fetchall()

【讨论】:

感谢您的意见。我已经修改了,现在我得到了cx_Oracle.DatabaseError: ORA-01830: date format picture ends before converting entire input string 由于 Oracle 有一个 statement cache,因此显式的 prepare() 可能没有什么好处 这是真的,并且 光标缓存 工作正常@ChristopherJones。所以在这个简单的例子中不会有 visible 效果。无论如何,IMO 建议大规模应用程序中使用prepared statements仍然有效。

以上是关于传入 Python 列表时的非法变量名称/编号的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01036: 非法的变量名/编号 解决方案

ora-01036: 非法的变量名/编号

SPSS13.变量名包含非法的首字符 为啥

来自 .Net 的 Oracle 参数化查询

如何在 Python 中将大量变量传入和传出函数?

python笔记——函数与变量作用域