将单个绑定变量和列表变量都传递给 SQL 查询 cx_Oracle Python

问题描述 投票:0回答:3

我有一个 Oracle SQL 查询:

SELECT * from table1 WHERE deliveredDate = ? AND productID IN (?,?,?,...);

我想使用 cx_Oracle 和 Python 将单个变量传递给 deliveredDate 和一个长度未知的列表

来自 Oracle 使用绑定指南 (https://cx-oracle.readthedocs.io/en/latest/user_guide/bind.html) 我知道您可以绑定单个变量或项目列表,但我'我不确定我们是否可以绑定两者。

请帮我解决这个问题。

谢谢。

python oracle cx-oracle bind-variables
3个回答
0
投票

当然可以,但是将绑定变量的符号从

?
转换为
:
前面的整数,例如

import pandas as pd
import cx_Oracle
import datetime

conn = cx_Oracle.connect('un/pwd@ip:port/db')
cur = conn.cursor()

sql  = """
       SELECT *
         FROM table1
        WHERE deliveredDate = :0 AND productID IN (:1,:2)   
       """
cur.execute(sql,[datetime.datetime(2022, 5, 3),1,2])

res = cur.fetchall()

print(res)

0
投票

您问题的关键部分是 IN 子句的“未知长度”。 cx_Oracle 文档Binding Multiple Values to a SQL WHERE IN Clause 显示了各种解决方案,每个解决方案都有一些优缺点,具体取决于列表的大小和语句将执行的次数。在大多数情况下,由于性能影响,您不希望绑定到语句 IN 列表中的单个占位符。如果 IN 列表的大小有上限,则放置那么多的占位符并为所有未知值绑定 None。文档示例更好地解释了它:

cursor.execute("""
        select employee_id, first_name, last_name
        from employees
        where last_name in (:name1, :name2, :name3, :name4, :name5)""",
        name1="Smith", name2="Taylor", name3=None, name4=None, name5=None)
for row in cursor:
    print(row)

(这使用关键字参数来匹配绑定占位符,但您可以改用列表)。

其他解决方案显示在该文档链接中。


0
投票

您可以使用连接方式通过分隔符分割字符串。你只需要传递一个变量,一个像 '46083,46092,46093,46096,46098,46111,46119' .

这样的字符串

它也适用于字符串中不断变化的项目编号。

它可能会给 SQL 增加一点开销,但如果您的查询运行几秒或更长时间,那没关系。就我而言,它给出了大约 ~0,064 秒到 30-60 个项目的运行时间。

select * from MYTABLE where
id in
(
    SELECT regexp_substr( :MYLIST ,'[^,]+', 1, level) myid FROM dual
    CONNECT BY regexp_substr( :MYLIST , '[^,]+', 1, level) IS NOT NULL
)
© www.soinside.com 2019 - 2024. All rights reserved.