我正在尝试创建一个过程,该过程在找到所有必要的数据打印在屏幕上之后,每个都打印一次。 此过程将搜索成员,并接收两个参数,如果您要通过ID(姓氏或国家ID)查找成员,则输入P_CRITERIO,以及具有ID,姓氏或国家ID的P_SOCIO。
我尝试删除Exception部分,但没有得到相同的错误,但仍然有一个无法修复的错误
CREATE OR REPLACE PROCEDURE P_CONSULTAR_SOCIOS (P_CRITERIO IN VARCHAR2,P_SOCIO IN VARCHAR2)
IS
V_SENT_SOCIO SOC_SOCIO%rowtype;
V_DEUDA NUMBER;--total dept
V_SALDO NUMBER;--available money
capital_pagado NUMBER;--how much he has paid
capital_a_pagar NUMBER;--how much he has to pay
V_APORTES NUMBER;--total contributions
BEGIN
IF UPPER(P_CRITERIO) = 'ID' THEN
SELECT * INTO V_SENT_SOCIO FROM SOC_SOCIO WHERE ID_SOCIO=P_SOCIO;
ELSE IF UPPER(P_CRITERIO) = 'CEDULA' THEN
SELECT * INTO V_SENT_SOCIO FROM SOC_SOCIO WHERE CEDULA=P_SOCIO;
ELSE IF UPPER(P_CRITERIO) = 'APELLIDO' THEN
SELECT * INTO V_SENT_SOCIO FROM SOC_SOCIO WHERE APELLIDO=P_SOCIO;
END IF;
--available money
SELECT NVL(SALDO_DISPONIBLE,0) INTO V_SALDO
FROM AHO_CUENTA_AHORRO
WHERE ID_SOCIO = V_SENT_SOCIO.ID_SOCIO;
--calculates if he has any loan active and the amount is stored in V_DEUDA
select sum(capital_pagado) into capital_pagado from cre_prestamos where id_sol_cred=V_SENT_SOCIO.ID_SOCIO;
select sum(capital_a_pagar) into capital_a_pagar from cre_prestamos where id_sol_cred=V_SENT_SOCIO.ID_SOCIO and UPPER(estado)='A';
V_DEUDA := (capital_pagado - capital_a_pagar);
--sum of total contributions
select sum(nvl(sdo.monto,0)) into V_APORTES from soc_detalle_obligaciones sdo
join soc_obligaciones o on sdo.id_obligacion = o.id_obligacion
where o.ID_SOCIO=V_SENT_SOCIO.ID_SOCIO and o.tipo_obligacion = 'A';
--prints result
DBMS_OUTPUT.PUT_LINE('| '||V_SENT_SOCIO.ID_SOCIO||' | '||V_SENT_SOCIO.CEDULA||
' | '||V_SENT_SOCIO.NOMBRE_APELLIDO||' | '||' | '||V_SALDO||' | '||V_DEUDA||' | '||
V_APORTES||' |');
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(-20032,'El socio no existe');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Ha ocurrido un error');
END P_CONSULTAR_SOCIOS;
/
我得到的错误
42/1 PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following: ( begin case declare end exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge 47/23 PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: end not pragma final instantiable order overriding static member constructor map
答案 0 :(得分:4)
您的代码有问题。
要使用if修复错误,您可以使用此代码替换代码的那部分
IF UPPER(P_CRITERIO) = 'ID' THEN
SELECT * INTO V_SENT_SOCIO FROM SOC_SOCIO WHERE ID_SOCIO=P_SOCIO;
ELSIF UPPER(P_CRITERIO) = 'CEDULA' THEN
SELECT * INTO V_SENT_SOCIO FROM SOC_SOCIO WHERE CEDULA=P_SOCIO;
ELSIF UPPER(P_CRITERIO) = 'APELLIDO' THEN
SELECT * INTO V_SENT_SOCIO FROM SOC_SOCIO WHERE APELLIDO=P_SOCIO;
END IF;
您的例外情况有误。
PUT_LINE不能接受多个参数
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('El socio no existe');
那是我到目前为止所能看到的
答案 1 :(得分:2)
PLS-00103: Encountered the symbol
异常始终表示语法错误。因此,通过查看给定行号上方的代码(在这种情况下为42)并与the syntax given in the Oracle PL/SQL documentation进行比较,很容易解决。
您遇到的问题是您的代码可能有效,但无效。您已撰写
IF ...
ELSE IF
现在,当第二个IF嵌套时,这是有效的语法:
IF ...
ELSE IF ... END IF;
END IF;
在这种情况下,每个独立IF都与END IF匹配。但是您实际上是在尝试实现一个开关。因此,您只有一个END IF。在这种情况下,您必须改为使用ELSIF:
IF ...
ELSIF ...
END IF;
EXCEPTION块中还有另一个语法错误。 DBMS_OUTPUT.PUT_LINE()采用一个参数,即字符串。要返回带有用户定义号码的消息,请使用RAISE_APPLICATION_ERROR()函数。
WHEN OTHERS分支只是不好的做法。字面上有成千上万条Oracle错误消息,其中许多可能会使您的过程失败。将所有这些压缩为一条通用消息对尝试诊断程序失败的任何人都无济于事。最初将是您,所以请帮助自己以及在您之后维护它的人们。同样,引发异常比使用DBMS_OUTPUT更好:消息可以忽略或不被注意,必须处理异常。
EXCEPTION
WHEN NO_DATA_FOUND THEN
raise_application_error(-20032,'El socio no existe');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Ha ocurrido un error');
raise;
END P_CONSULTAR_SOCIOS;