我有这样的查询:
SELECT prodId, prod_name , prod_type FROM mytable WHERE prod_type in (:list_prod_names)
我想获取产品的信息,具体取决于可能的类型:"day", "week", "weekend", "month"
。根据日期的不同,可能至少是这些选项之一,或者是所有选项的组合。
此信息(列表类型)由函数prod_names(date_search)
返回
我正在使用cx_oracle绑定,其代码如下:
def get_prod_by_type(search_date :datetime):
query_path = r'./queries/prod_by_name.sql'
raw_query = open(query_path).read().strip().replace('\n', ' ').replace('\t', ' ').replace(' ', ' ')
print(sql_read_op)
# Depending on the date the product types may be different
prod_names(search_date) #This returns a list with possible names
qry_params = {"list_prod_names": prod_names} # See attempts bellow
try:
db = DB(username='username', password='pss', hostname="localhost")
df = db.get(raw_query,qry_params)
except Exception:
exception_error = traceback.format_exc()
exception_error = 'Exception on DB.get_short_cov_op2() : %s\n%s' % exception_error
print(exception_error)
return df
为此:qry_params = {"list_prod_names": prod_names}
我尝试了多种不同的方法,例如:
prod_names = ''.join(prod_names)
prod_names = str(prod_names)
prod_names =." \'"+''.join(prod_names)+"\'"
我设法使它起作用的唯一方法是:
new_query = raw_query.format(list_prod_names=prodnames_for_date(search_date)).replace('[', '').replace(']','')
df = db.query(new_query)
我尝试不使用.format()
,因为对SQL执行.format来防止攻击是一种不好的做法。
db.py
包含其他功能:
def get(self, sql, params={}):
cur = self.con.cursor()
cur.prepare(sql)
try:
cur.execute(sql, **params)
df = pd.DataFrame(cur.fetchall(), columns=[c[0] for c in cur.description])
except Exception:
exception_error = traceback.format_exc()
exception_error = 'Exception on DB.get() : %s\n%s' % exception_error
print(exception_error)
self.con.rollback()
cur.close()
df.columns = df.columns.map(lambda x: x.upper())
return df
我希望能够进行类型绑定。
我正在使用:
我已经阅读了Followig文章,但仍然找不到解决方法:
答案 0 :(得分:2)
不幸的是,除非将其转换为SQL类型并使用子查询,否则无法直接绑定数组,这非常复杂。因此,您需要执行以下操作:
inClauseParts = []
for i, inValue in enumerate(ARRAY_VALUE):
argName = "arg_" + str(i + 1)
inClauseParts.append(":" + argName)
clause = "%s in (%s)" % (columnName, ",".join(inClauseParts))
这很好用,但是请注意,如果数组中元素的数目定期更改,则使用此技术将创建一个单独的语句,必须针对每个元素数目进行分析。如果您知道(通常)数组中的元素个数不超过(例如)10个,则最好将None附加到传入数组中,以使元素数始终为10。
希望这很清楚!
答案 1 :(得分:0)
我终于设法做到了。它可能并不漂亮,但是可以工作。
我已经修改了我的slq查询,使其包含一个额外的选择,该选择返回了我的描述符列表的值:
inner join (
SELECT regexp_substr(:my_list_of_items, '[^,]+', 1, LEVEL) as mylist
FROM dual
CONNECT BY LEVEL <= length(:my_list_of_items) - length(REPLACE(:my_list_of_items, ',', '')) + 1
) d
on d.mylist= a.corresponding_columns