Di Zou Di Zou - 15 days ago 6
Python Question

How do I run non query sql commands using cx_Oracle?

I am trying to run these commands using cx_oracle:

begin
add_command_pkg.add_command
( command_id => 7,
expiry_time => sysdate + 7
);

add_command_pkg.add_command
( command_id => 12,
expiry_time => sysdate + 7
);
commit;
end;


So this is my Python code:

dsn = cx_Oracle.makedsn(hostname, port, sid)
orcl = cx_Oracle.connect(username + '/' + password + '@' + dsn)

curs = orcl.cursor()
cmd = "begin \n\
add_command_pkg.add_command \n\
( command_id => 7, \n\
expiry_time => sysdate + 7 \n\
); \n\
\n\
add_command_pkg.add_command \n\
( command_id => 12, \n\
expiry_time => sysdate + 7 \n\
); \n\
commit; \n\
end;"

curs.execute(cmd)
orcl.close()


When I run this code, I get this error:


cx_Oracle.InterfaceError: not a query


So how do I run these sql commands that aren't queries using cx_oracle?

Edit:

After making changes this is what I have now:

curs.callproc('add_command_pkg.add_command', [],
{ 'command_id' : 7,
'session_id' : 'null',
'p_expiry_time' : 'sysdate + 7',
'config_id' : 6 })


When I run this, I get this error:


File "N:\App\MainWidget.py", line 456, in myFunc

'config_id' : 6 })

cx_Oracle.DatabaseError: ORA-01858: a non-numeric character was found where a numeric was expected

ORA-06512: at line 1


Also, how do I commit this?

Ben Ben
Answer

The best way is to call the procedure directly using callproc.

curs.callproc['add_command_pkg.add_command',['7', 'sysdate + 7']]
orcl.commit()

or if you need to use keyword arguments directly use a dictionary not a list.

curs.callproc['add_command_pkg.add_command'
             , {'command_id' : '7', 'expiry_time' : 'sysdate + 7'}]
orcl.commit()

The actual syntax is

curs.callproc['package_name.procedure_name'
             , ['list_argument1', 'list_argument2']
             , {'keyword_argument1' : 'keyword1'}
             ]

Which is the same as the following in Oracle

begin
    package_name.procedure_name( 'list_argument1', 'list_argument2'
                               , keywork_argument1 => 'keyword1');
end;

Whilst I'm about the connect method can be called in the following way without the need for concatenation:

 cx_Oracle.connect(username, password, dsn)
Comments