4

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]}
2

1 Answer 1

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.