lists in cx_Oracle
Daniel Dittmar
daniel.dittmar at sap.corp
Tue May 3 08:38:13 EDT 2005
Andrew Dalke wrote:
> I want to execute a query with an "IN" in the WHERE clause
> and with the parameter taken from a Python variable. That
> is, I wanted something like this to work
>
> id_list = ["AB001", "AB002", "AB003"]
>
> c.execute("""SELECT s.smiles FROM smiles_database s WHERE """
> """ s.id IN :id_list""", id_list = id_list)
>
> I couldn't get it to work. It complained
>
> arrays can only be bound to PL/SQL statements
>
Possible workarounds:
- use executemany: a few databases allow to execute several sets of
input parameters at once. And even fewer allow this for SELECTs, where
the result is one cursor created from the UNION of a SELECt for each set
of input parameters. Apart from being unlikely to work, this also
requires that *all* input parameters are lists of the same length
(unless the driver is smart enough to expand skalars to lists in this
context)
- specify a maximum number of input parameters 's.id in (:id0, :id1,
...)' and fill missing values with the first value
- create a class for this purpose. Statement are created on the fly, but
with placeholders so you don't run into the SQL Injection problem. As
it's an object, you could cache these generated statements base on the
size of the list
- create a temporary table, insert all the values into that table
(executemany is great for INSERTS) and then join with that table
You could also search comp.language.java.database where this is a
frequent question.
It is unlikely that this can be solved at the driver level. Without
support from the database, the driver would have to manipulate the SQL
statement. And there are few predicates where a list parameter is
useful. Expanding a list always yould lead to very bizarre error
messages. Expanding them only where useful would require a SQL parser.
Daniel
More information about the Python-list
mailing list