I have following SQL
select * from my_table
where my_param in :params
How do I bind python list or another array to cx_Oracle cursor execute expression?
This does not work
cursor.execute(my_sql, {'params': [1, 2, 3]}
I have following SQL
select * from my_table
where my_param in :params
How do I bind python list or another array to cx_Oracle cursor execute expression?
This does not work
cursor.execute(my_sql, {'params': [1, 2, 3]}
After searching around for a long time, I found this solution most elegant for me to pass a list to a oracle sql statement.
It requires that you can create new types within the database.
create a nested table type in the database
create type t_id_tab as table of number;
Please note that in oracle 11 this must be done on schema level and not within a package. Otherwise our statement (see next step) will not work.
the python script
With cx_Oracle one can use the object api to create a new object of custom types. This object can than be passed to the query.
import cx_Oracle
db = cx_Oracle.connect("my_user", "my_password", "<host>:<port>/<sid>")
cursor = db.cursor()
id_list_type = db.gettype("t_id_tab")
id_list = id_list_type.newobject([1, 2, 3, 4])
cursor.execute("select * from my_table where my_param in (select column_value from table (:id_values))", id_values=id_list)
Untested version for oracle 12 onwards
It is said,that from oracle12 onwards the same sql syntax as above works also for associative arrays. I cannot test it. But if this is right, this should work without creating a custom collection type;
import cx_Oracle
db = cx_Oracle.connect("my_user", "my_password", "<host>:<port>/<sid>")
cursor = db.cursor()
id_list = cursor.arrayvar(cx_Oracle.NUMBER, [1, 2, 3, 4])
cursor.execute("select * from my_table where my_param in (select column_value from table (:id_values))", id_values=id_list)