cx_Oracle clause IN using a variable
Hans Mulder
hansmu at xs4all.nl
Tue Oct 16 13:22:43 EDT 2012
On 16/10/12 15:41:58, Beppe wrote:
> Hi all,
> I don't know if it is the correct place to set this question, however,
> I'm using cx_Oracle to query an Oracle database.
> I've a problem to use the IN clause with a variable.
> My statement is
>
> sql = "SELECT field1,field2,field3
> FROM my_table
> WHERE field_3 IN (:arg_1)"
>
> where arg_1 is retrive by a dictionary
> that is build so
>
> my_dict = {'location':"X",
> 'oracle_user':'user',
> 'oracle_password':'pass',
> 'dsn':'dsn',
> 'mailto':'someone at somewhere.org',
> 'codes':"CNI,CNP"}
>
> args = (dict['codes'],)
>
>
> con = cx_Oracle.connect(my_dict["oracle_user"],
> my_dict["oracle_password"],
> my_dict["dsn"])
>
> cur = con.cursor()
> cur.execute(sql,args)
> rs = cur.fetchall()
>
> but it doesn't work in the sense that doesn't return anything
>
> If i use the statment without variable
>
> SELECT field1,field2,field3
> FROM my_table
> WHERE field_3 IN ('CNI','CNP')
>
> the query works
>
> what is wrong?
You only have a single placeholder variable,
so your statement is equivalent to
SELECT field1,field2,field3
FROM my_table
WHERE field_3 IN ('CNI,CNP')
Presumably 'CNI,CNP' is not a valid value for field_3,
thus your query finds no records.
> suggestions?
To verify that you have the correct syntax, try it
with a single value first:
my_dict = {'location':"X",
'oracle_user':'user',
'oracle_password':'pass',
'dsn':'dsn',
'mailto':'someone at somewhere.org',
'codes':"CNI"}
It that produces some of the records you want, then the
question is really: can you somehow pass a list of values
via a single placeholder variable?
I'm, not a cx_Oracle expert, but I think the answer is "no".
If you want to pass exactly two values, then the work-around
would be to pass them in separate variables:
my_dict = {'location':"X",
'oracle_user':'user',
'oracle_password':'pass',
'dsn':'dsn',
'mailto':'someone at somewhere.org',
'code1':"CNI",
'code2':"CNP"}
sql = """SELECT field1,field2,field3
FROM my_table
WHERE field_3 IN (:arg_1, :arg_2)"""
args = (my_dict['code1'],my_dict['code2'])
If the number of codes can vary, you'll have to generate a
query with the correct number of placholders in it. Mabye
something like this (untested):
my_dict = {'location':"X",
'oracle_user':'user',
'oracle_password':'pass',
'dsn':'dsn',
'mailto':'someone at somewhere.org',
'codes':"Ornhgvshy,vf,orggre,guna,htyl"}
args = my_dict['codes'].split(",")
placeholders = ','.join(":x%d" % i for i,_ in enumerate(args))
sql = """SELECT field1,field2,field3
FROM my_table
WHERE field_3 IN (%s)""" % placeholders
con = cx_Oracle.connect(my_dict["oracle_user"],
my_dict["oracle_password"],
my_dict["dsn"])
cur = con.cursor()
cur.execute(sql,args)
rs = cur.fetchall()
Hope this helps,
-- HansM
More information about the Python-list
mailing list