cx_Oracle clause IN using a variable
Beppe
giuseppecostanzi at gmail.com
Wed Oct 17 09:49:30 EDT 2012
Il giorno martedì 16 ottobre 2012 19:23:22 UTC+2, Hans Mulder ha scritto:
> 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
Thanks a lot of to ian and hans for your explanations that have allowed me to resolve my problem and above all to understand the why I was wrong.
regards
beppe
More information about the Python-list
mailing list