我正在尝试创建一个使用 Oracle 过程进行操作的 CRUD 应用程序。 每个过程都有异常,并且有一个与之关联的触发器,但是当使用 Python 代码时,它们都不会得到处理。 例如,如果我尝试输入重复的 ID,它应该处理异常,因为它们应该是唯一的。在 Oracle 上执行时工作正常,但从 Python 执行时,它的行为就好像记录已插入,尽管事实并非如此。
这是Python代码的插入部分
import cx_Oracle
#INSERT EMPLOYEE
def crearEmpleado():
validEmpno = False
while(not validEmpno):
p_empno = input('Ingrese el número de empleado: ')
if p_empno.isnumeric() and int(p_empno) > 0 and int(p_empno) <= 999999:
validEmpno = True
p_empno = int(p_empno)
else:
print('Error')
validEname = False
while(not validEname):
p_ename = input('Ingrese el nombre del empleado: ')
if len(p_ename) > 0 and len(p_ename) <= 10:
validEname = True
else:
print('Error')
validJob = False
while(not validJob):
p_job = input('Ingrese el puesto del empleado: ')
if len(p_job) > 0 and len(p_job) <= 9:
validJob = True
else:
print('Error')
validMgr = False
while(not validMgr):
p_mgr = input('Ingrese el número de manager: ')
if p_mgr.isnumeric() and int(p_mgr) > 0 and int(p_mgr) <= 9999:
validMgr = True
p_mgr = int(p_mgr)
else:
print('Error')
validHiredate = False
while(not validHiredate):
p_hiredate = input('Ingrese la fecha de contratación en formato DD/MM/YYYY: ')
if len(p_hiredate) > 0 and len(p_hiredate) <= 10:
validHiredate = True
else:
print('Error')
validSal = False
while(not validSal):
p_sal = input('Ingrese el salario: ')
if float(p_sal) > 0 and float(p_sal) <= 99999.99:
validSal = True
p_sal = float(p_sal)
else:
print('Error')
validComm = False
while(not validComm):
p_comm = input('Ingrese el porcentaje de comisión: ')
if float(p_comm) <= 99999.99:
validComm = True
p_comm = float(p_comm)
else:
print('Error')
validDeptno = False
while(not validDeptno):
p_deptno = input('Ingrese el número de departamento: ')
if p_deptno.isnumeric() and int(p_deptno) > 0 and int(p_deptno) <= 99:
validDeptno = True
p_deptno = int(p_deptno)
else:
print('Error')
data = [p_empno, p_ename, p_job, p_mgr, p_hiredate, p_sal, p_comm, p_deptno]
return data
#CONECT
def connCrearEmpleado(data):
conn = cx_Oracle.connect('HR/hr@localhost:1521/xepdb1')
try:
cursor = conn.cursor()
cursor.callproc('add_emp', data)
print('\n¡Empleado registrado!\n')
except cx_Oracle.DatabaseError as err:
print('Database connection error: {}'.format(err))
print(err.code)
print(err.message)
print(err.context)
raise
这是正在使用的桌子:
CREATE TABLE emp (
empno NUMBER(4) NOT NULL,
ename VARCHAR2(10) NOT NULL,
job VARCHAR2(9) NOT NULL,
mgr NUMBER(4) NOT NULL,
hiredate DATE NOT NULL,
sal NUMBER(7,2) NOT NULL,
comm NUMBER(7,2),
deptno NUMBER(2) NOT NULL
)
这是 PL/SQL 过程:
create or replace PROCEDURE add_emp
(p_empno in NUMBER, p_ename in VARCHAR2, p_job in VARCHAR2, p_mgr in NUMBER, p_hiredate in VARCHAR2, p_sal in NUMBER, p_comm in NUMBER, p_deptno in NUMBER)
IS
v_empno NUMBER;
e_unique_empno EXCEPTION;
e_notnull_empno EXCEPTION;
e_notnull_ename EXCEPTION;
e_notnull_job EXCEPTION;
e_notnull_mgr EXCEPTION;
e_notnull_hiredate EXCEPTION;
e_valid_sal EXCEPTION;
e_notnull_sal EXCEPTION;
v_deptno NUMBER;
e_notnull_deptno EXCEPTION;
BEGIN
IF p_empno IS NULL THEN
RAISE e_notnull_empno;
ELSIF p_ename IS NULL THEN
RAISE e_notnull_ename;
ELSIF p_job IS NULL THEN
RAISE e_notnull_job;
ELSIF p_mgr IS NULL THEN
RAISE e_notnull_mgr;
ELSIF p_hiredate IS NULL THEN
RAISE e_notnull_hiredate;
ELSIF p_sal IS NULL THEN
RAISE e_notnull_sal;
ELSIF p_sal <= 0 THEN
RAISE e_valid_sal;
ELSIF p_deptno IS NULL THEN
RAISE e_notnull_deptno;
END IF;
SELECT COUNT(*) INTO v_empno FROM emp WHERE p_empno = empno;
IF v_empno > 0 THEN
RAISE e_unique_empno;
END IF;
INSERT INTO emp
VALUES(p_empno, UPPER(p_ename), UPPER(p_job), p_mgr, TO_DATE(p_hiredate, 'DD-MM-YYYY'), p_sal, p_comm, p_deptno);
COMMIT;
EXCEPTION
WHEN e_unique_empno THEN
dbms_output.put_line('El ID ya existe.');
WHEN e_notnull_empno THEN
dbms_output.put_line('El campo EMPNO no puede ser nulo.');
WHEN e_notnull_ename THEN
dbms_output.put_line('El campo ENAME no puede ser nulo.');
WHEN e_notnull_job THEN
dbms_output.put_line('El campo JOB no puede ser nulo.');
WHEN e_notnull_mgr THEN
dbms_output.put_line('El campo MGR no puede ser nulo.');
WHEN e_notnull_hiredate THEN
dbms_output.put_line('El campo HIRE_DATE no puede ser nulo.');
WHEN e_valid_sal THEN
dbms_output.put_line('El salario no puede ser menor o igual a cero.');
WHEN e_notnull_sal THEN
dbms_output.put_line('El campo SALARY no puede ser nulo.');
WHEN e_notnull_deptno THEN
dbms_output.put_line('El campo DEPTNO no puede ser nulo.');
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END add_emp;
/
从 Python 执行时不会引发任何 PL/SQL 异常
给表添加主键约束:
ALTER TABLE emp ADD CONSTRAINT emp__empno__pk PRIMARY KEY(empno);
然后不要捕获异常并将错误打印到控制台。让异常被引发并让
PRIMARY KEY
和 NOT NULL
约束完成其工作,而不是尝试手动执行完全相同的操作。
CREATE PROCEDURE add_emp(
p_empno in EMP.EMPNO%TYPE,
p_ename in EMP.ENAME%TYPE,
p_job in EMP.JOB%TYPE,
p_mgr in EMP.MGR%TYPE,
p_hiredate in VARCHAR2,
p_sal in EMP.SAL%TYPE,
p_comm in EMP.COMM%TYPE,
p_deptno in EMP.DEPTNO%TYPE
)
IS
BEGIN
INSERT INTO emp(
empno,
ename,
job,
mgr,
hiredate,
sal,
comm,
deptno
) VALUES(
p_empno,
UPPER(p_ename),
UPPER(p_job),
p_mgr,
TO_DATE(p_hiredate, 'DD-MM-YYYY'),
p_sal,
p_comm,
p_deptno
);
END add_emp;
/