ZDV
ZDV

Reputation: 23

Calling a stored function from oracle DB with cx_Oracle in Python

I am not familiar with PL/SQL and just can't transform a working raw query into python code.

Here is the raw query:

DECLARE
  returntype MY_PKG_1.MY_DATA_TYPE;
BEGIN
  SELECT *
   BULK COLLECT INTO returntype
  FROM TABLE(MY_PKG_2.MY_FUNC(
    param_1 => 'some data',
    param_2 => 'some more data'
  ));
END;

It is a valid query that works just fine, I can run it with cursor.execute() with no errors. But how to get the returned rows? I've tried the following:

returntype = connection.gettype('MY_PKG_1.MY_DATA_TYPE')
cursor = connection.cursor()
results = cursor.callfunc('MY_PKG_2.MY_FUNC', returntype, ['some data', 'some more data'])
cursor.commit()

But I get an error "ORA-04043: object MY_PKG_1.MY_DATA_TYPE does not exist".

Upvotes: 0

Views: 877

Answers (1)

Christopher Jones
Christopher Jones

Reputation: 10506

If the PL/SQL block just does a single query, then execute that query directly without using PL/SQL:

with connection.cursor() as cursor:
    try:
        for r in cursor.execute('SELECT * FROM TABLE(MY_PKG_2.MY_FUNC(param_1 => :p1, param_2 => :p2))', p1='some more data', p2='some data')
            print(r)
    except cx_Oracle.Error as e:
        error, = e.args
        print(error.message)
        print(sql)
        if (error.offset):
            print('^'.rjust(error.offset+1, ' '))

Otherwise you will have to bind a REF CURSOR, or use Implicit Results. See the cx_Oracle examples ref_cursor.py and implicit_results.py.

If you are returning collections etc, then this gives some insights into generically traversing them. But check the doc for simpler examples.

Also see the cx_Oracle doc on tuning fetch performance.

Upvotes: 1

Related Questions