Как обработать ошибку в пакете ibm_db при вызове хранимой процедуры? - PullRequest
0 голосов
/ 31 октября 2019

Я пытаюсь вызвать хранимую процедуру, используя следующий код

conn = ibm_db.connect("database","username","password") sql = "CALL DB2INST1.KPI_VALIDATE()" stmt = ibm_db.exec_immediate(conn, sql)

Но эта процедура не возвращает никаких строк и будет только возвращать код. Теперь мне нужно обработать ошибку независимо от того, успешно ли выполняется процедура. Может ли кто-нибудь помочь мне, как справиться с этим?

Спасибо

1 Ответ

1 голос
/ 31 октября 2019

В целях тестирования я создал таблицу:

db2 "create table so(c1 int not null primary key)"

, и моя процедура просто вставит строку в эту таблицу - это позволит мне легко вызвать ошибку с дублирующим ключом:

db2 "create or replace procedure so_proc(in insert_val int)
    language sql
    insert into so values(insert_val)"

db2 "call so_proc(1)"

  Return Status = 0
db2 "call so_proc(1)"
SQL0803N  One or more values in the INSERT statement, UPDATE statement, or 
foreign key update caused by a DELETE statement are not valid because the 
primary key, unique constraint or unique index identified by "1" constrains 
table "DB2V115.SO" from having duplicate values for the index key.  
SQLSTATE=23505

теперь с Python:

conn = ibm_db.connect("DATABASE=SAMPLE;HOSTNAME=localhost;PORT=61115;UID=db2v115;PWD=xxxxx;","","")  
stmt = ibm_db.exec_immediate(conn, "CALL SO_PROC(2)")
stmt = ibm_db.exec_immediate(conn, "CALL SO_PROC(2)") 

Exception                                 Traceback (most recent call last)
<ipython-input-8-c1f4b252e70a> in <module>
----> 1 stmt = ibm_db.exec_immediate(conn, "CALL SO_PROC(2)")

Exception: [IBM][CLI Driver][DB2/LINUXX8664] SQL0803N  One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "DB2V115.SO" from having duplicate values for the index key.  SQLSTATE=23505 SQLCODE=-803

, поэтому, если процедура обнаружит исключение, вы получите его, вам просто нужно обработать исключение Try/Except block:

try:
    stmt = ibm_db.exec_immediate(conn, "CALL SO_PROC(2)")
except Exception:
    print("Procedure failed with sqlstate {}".format(ibm_db.stmt_error()))
    print("Error {}".format(ibm_db.stmt_errormsg()))

Procedure failed with sqlstate 23505
Error [IBM][CLI Driver][DB2/LINUXX8664] SQL0803N  One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "DB2V115.SO" from having duplicate values for the index key.  SQLSTATE=23505 SQLCODE=-803

Или вас на самом деле интересует CALL код возврата / статус? Например:

create or replace procedure so_proc_v2(in insert_val int)
    language sql
    if not exists (select 1 from so where c1 = insert_val)
    then 
        insert into so values(insert_val);
        return 0;
    else 
        return -1;
    end if@

test:

db2 "call so_proc_v2(10)"

  Return Status = 0

db2 "call so_proc_v2(10)"

  Return Status = -1

, тогда это немного сложно. При включенной трассировке CLI (у меня установлен ibm_db в моем локальном пути, поэтому он также получил пакет CLI):

export LD_LIBRARY_PATH=$HOME/.local/lib/python3.7/site-packages/clidriver/lib/
$HOME/.local/lib/python3.7/site-packages/clidriver/bin/db2trc on -cli -f /tmp/cli/trc
<run_code>
$HOME/.local/lib/python3.7/site-packages/clidriver/bin/db2trc off
$HOME/.local/lib/python3.7/site-packages/clidriver/bin/db2trc fmt -cli /tmp/cli.trc /tmp/cli.fmt

trace показывает состояние возврата:

SQLExecute( hStmt=1:8 )
    ---> Time elapsed - -7.762688E+006 seconds
( Row=1, iPar=1, fCType=SQL_C_LONG, rgbValue=10 )
( return=-1 )
( COMMIT REQUESTED=1 )
( COMMIT REPLY RECEIVED=1 )

, ноВ python-ibmdb API я не вижу способа получить его ... (например, ibm_dbcallproc не имеет такой опции). Это означает, что если я что-то упустил, вам придется поднять проблему на Github, чтобы расширить API

...