Come posso eseguire comandi SQL non query usando CX_ORACLE?
Domanda
Sto cercando di eseguire questi comandi usando 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;
Quindi questo è il mio codice Python:
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()
Quando eseguo questo codice, ricevo questo errore:
cx_oracle.interfaceerror: non una query
Quindi, come posso eseguire questi comandi SQL che non sono query usando CX_ORACLE?
Modificare:
Dopo aver apportato modifiche, questo è quello che ho ora:
curs.callproc('add_command_pkg.add_command', [],
{ 'command_id' : 7,
'session_id' : 'null',
'p_expiry_time' : 'sysdate + 7',
'config_id' : 6 })
Quando eseguo questo, ricevo questo errore:
File "N: app mainwidget.py", riga 456, in myfunc
'config_id': 6})
cx_oracle.databaseerror: ORA-01858: è stato trovato un carattere non numerico in cui era previsto un numerico
ORA-06512: alla riga 1
Inoltre, come faccio a commettere questo?
Soluzione
Il modo migliore è chiamare direttamente la procedura utilizzando callproc
.
curs.callproc['add_command_pkg.add_command',['7', 'sysdate + 7']]
orcl.commit()
o se è necessario utilizzare gli argomenti delle parole chiave, utilizzare direttamente un dizionario non un elenco.
curs.callproc['add_command_pkg.add_command'
, {'command_id' : '7', 'expiry_time' : 'sysdate + 7'}]
orcl.commit()
La sintassi effettiva è
curs.callproc['package_name.procedure_name'
, ['list_argument1', 'list_argument2']
, {'keyword_argument1' : 'keyword1'}
]
Che è lo stesso di quanto segue in Oracle
begin
package_name.procedure_name( 'list_argument1', 'list_argument2'
, keywork_argument1 => 'keyword1');
end;
Mentre sono il connect
Il metodo può essere chiamato nel modo seguente senza la necessità di concatenazione:
cx_Oracle.connect(username, password, dsn)