简体   繁体   English

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

[英]Illegal Variable Name/Number when Passing in Python List

I'm trying to run SQL statements through Python on a list.我正在尝试通过列表上的 Python 运行 SQL 语句。 By passing in a list, in this case date.通过传入一个列表,在这种情况下是日期。 Since i want to run multiple SELECT SQL queries and return them.因为我想运行多个 SELECT SQL 查询并返回它们。 I've tested this by passing in integers, however when trying to pass in a date I am getting ORA-01036 error.我通过传入整数对此进行了测试,但是当尝试传入日期时,我收到 ORA-01036 错误。 Illegal variable name/number.非法变量名称/编号。 I'm using an Oracle DB.我正在使用 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)

Any suggestions to make this run?有什么建议可以运行吗?

Some recommendation and wanings to your approach :对您的方法的一些建议和不足:

  • you should not depend on your default NLS date setting, while binding a String (eg "'01-DEC-21'" ) to a DATE column.在将String (例如"'01-DEC-21'" )绑定到DATE列时,您不应依赖默认的NLS日期设置。 (You probably need also remone one of the quotes). (您可能还需要重新引用其中一个引号)。

  • You should ommit to fetch data in a loop if you can fetch them in one query (using an IN list)如果可以在一个查询中获取数据(使用IN列表),则应该省略循环获取数据

  • use prepared statement使用准备好的语句

Example例子

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

This generates the query that uses bind variables for your input list这会生成为您的输入列表使用绑定变量的查询

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

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

The sql_query generate is 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') )

Note the usage of to_date with explicite mask and fixing the language to avoid problems with interpretation of the month abbreviation.请注意使用带有显式掩码的to_date并修复语言以避免月份缩写的解释问题。 (eg ORA-01843: no a valid month ) (例如ORA-01843: no a valid month

Now you can use the query to fetch the data in one pass现在您可以使用查询一次性获取数据

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

You can't name a bind variable date , it's an illegal name.您不能命名绑定变量date ,这是一个非法名称。 Also your named variable in cursor.execute should match the bind variable name.此外,您在cursor.execute中的命名变量应与绑定变量名称匹配。 Try something like:尝试类似:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM