【问题标题】:Passing two or more parameters to Oracle SQL将两个或多个参数传递给 Oracle SQL
【发布时间】:2021-08-08 08:09:49
【问题描述】:

我正在尝试为两个参数定义一个值列表(id 编号)并将它们传递给查询 Oracle 表的 SQL。

只要我只包含一个 id 和一个参数,这段代码就可以工作

idlist = ['SLCTD']
in_vars = ','.join(':%d' % i for i in range(len(idlist)))
query = """
select PEBEMPL_ECLS_CODE 
from PEBEMPL
inner join SPRIDEN on spriden_pidm = pebempl_pidm 
where SPRIDEN_CHANGE_IND is null
and SPRIDEN_ID in (%s)
""" % in_vars
df = pd.read_sql(query, connection, params=idlist)

现在已经用两个参数尝试了以下方法,但失败了:

idlist = [735,'SLCTD']
in_vars = ','.join(':%d' % i for i in range(len(idlist)))
query = """
select PEBEMPL_ECLS_CODE 
from PEBEMPL
inner join SPRIDEN on spriden_pidm = pebempl_pidm 
where SPRIDEN_CHANGE_IND is null
and PLANNING_WEEK in (%s)
and SPRIDEN_ID in (%s)
""" % in_vars
df = pd.read_sql(query, connection, params=idlist)

请指教

【问题讨论】:

  • 失败了 - 请粘贴你得到的错误。您的错误与 SQL 无关,字符串格式化失败,因为当有两个占位符时,您只传递了一个参数。所以真正的问题是:如何用两个参数格式化字符串
  • 您不能将绑定变量连接成单个绑定变量并将其传递给 oracle 中的 IN 运算符。 IN (:B) 只会考虑整个字符串。如果在 IN 运算符中有多个值,那么每个值都必须作为单独的绑定变量传递。像这样:IN (:B1,:B2,:B3)
  • @koenlosrie 上面的代码应该生成与列表中的元素一样多的未命名变量,因此在execute 中,该语句将有足够的绑定变量来绑定。问题在于字符串插值
  • 错误发生在"和 SPIDEN_ID in (%s) """ % in_vars 行。错误消息是“格式字符串的参数不足。”。注意:此查询位于 Python3 脚本中。
  • 对于未来的读者,Binding Multiple Values to a SQL WHERE IN Clause 上的 cx_Oracle 文档可能会有用。

标签: python sql oracle


【解决方案1】:

Oracle 有以下几点:

如果你从 tty 执行脚本你需要做的:

sqlplus $USER/$PASSWD @file.sql param_1 param_2

进入你可能有的file.sql:

SELECT '$1', '$2' FROM DUAL;

其中$1是第一个参数,$2是第二个参数,如果你想要更多,你可以放任意多的参数。

如果您从 python 调用脚本。 您必须:

python3 file.py param_1 param_2 ... param_n

进入文件.py

import sys
sys.argv[1] --> param_1
sys.argv[2] --> param_2
sys.argv[n] --> param_n

【讨论】:

    【解决方案2】:

    对于字符串格式问题,请在 Python 3 中尝试this

    idlist = ['SLCTD']
    in_vars = ','.join(':bv%d' % i for i in range(len(idlist)))
    query = """
    select PEBEMPL_ECLS_CODE 
    from PEBEMPL
    inner join SPRIDEN on spriden_pidm = pebempl_pidm 
    where SPRIDEN_CHANGE_IND is null
    and PLANNING_WEEK in ({})
    and SPRIDEN_ID in ({})
    """.format(in_vars,in_vars)
    
    print(query)
    

    输出是:

    select PEBEMPL_ECLS_CODE 
    from PEBEMPL
    inner join SPRIDEN on spriden_pidm = pebempl_pidm 
    where SPRIDEN_CHANGE_IND is null
    and PLANNING_WEEK in (:bv0)
    and SPRIDEN_ID in (:bv0)
    

    由于您正在重用绑定变量“名称”(bv0),因此您需要在执行时执行“按名称绑定”,我将把它留给您做练习。

    【讨论】:

    • 谢谢克里斯托弗。您的解决方案对我有用,尽管它似乎有点违反直觉。尽管 id_list 现在包含多个参数,但我保留了原始 pd.read.sql 语句。我假设您可以将其扩展为三个或更多参数。
    猜你喜欢
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 2012-12-12
    • 2020-12-15
    • 2011-08-06
    • 2016-07-18
    • 2013-01-07
    • 2011-10-10
    相关资源
    最近更新 更多