internal error [phdite:node kind] / looping chain of synonyms - oracle

I am getting these errors when executing my code, can anyone give me a solution please?
create or replace procedure old_candidate (ID_M1 candidate.ID_M1%type,ID_M2 candidate.ID_M2%type,ID_M3 candidate.ID_M3%type,ID_M4 candidate.ID_M4%type,nombre_masterss candidate.nombre_masters%type,Lname candidate.Lname%type,Fname candidate.Fname%type,Fname_father candidate.Fname_father%type,mother candidate.mother%type,sex candidate.sex%type,DOB candidate.DOB%type,POB candidate.POB%type,Nat candidate.Nat%type,ncivil candidate.ncivil%type,Cir candidate.Cir%type,building candidate.building%type,street candidate.street%type,region candidate.region%type,nhood candidate.nhood%type,tel_m candidate.tel_m%type,tel_f candidate.tel_f%type,email candidate.email%type,Hschool candidate.Hschool%type,description candidate.description%type,diploma1 candidate.diploma1%type,desc_d1 candidate.desc_d1%type,Diploma2 candidate.Diploma2%type,desc_d2 candidate.desc_d2%type,Diploma3 candidate.Diploma3%type,desc_d3 candidate.desc_d3%type,motivation_m1 candidate.motivation_m1%type,motivation_m2 candidate.motivation_m2%type,motivation_m3 candidate.motivation_m3%type,motivation_m4 candidate.motivation_m4%type)
is
IDs students.ID%type;
pre master.prerequis%type;
test number;
begin
select ID
into IDs
from students
where ID_u=get_current_user_ID;
if nombre_masterss>0 then
select prerequis
into pre
from master
where ID_master=ID_m1;
if pre>0 then select count(*)
into test
from inscriptions
where master_ID=pre and succeeded='Y';
if test=0 then
raise_application_error(-20018,'vous ne pouvez pas s''inscrire au master1 avant de reussir son prerequis');
end if;
end if;
end if;
if nombre_masterss>1 then
select prerequis
into pre
from master
where ID_master=ID_m2;
if pre>0 then select count(*)
into test
from inscriptions
where master_ID=pre and succeeded='Y';
if test=0 then
raise_application_error(-20018,'vous ne pouvez pas s''inscrire au master2 avant de reussir son prerequis');
end if;
end if;
end if;
if nombre_masterss>2 then
select prerequis
into pre
from master
where ID_master=ID_m3;
if pre>0 then select count(*)
into test
from inscriptions
where master_ID=pre and succeeded='Y';
if test=0 then
raise_application_error(-20018,'vous ne pouvez pas s''inscrire au master3 avant de reussir son prerequis');
end if;
end if;
end if;
if nombre_masterss>3 then
select prerequis
into pre
from master
where ID_master=ID_m4;
if pre>0 then select count(*)
into test
from inscriptions
where master_ID=pre and succeeded='Y';
if test=0 then
raise_application_error(-20018,'vous ne pouvez pas s''inscrire au master4 avant de reussir son prerequis');
end if;
end if;
end if;
insert into candidate (ID_c,year,old_new,ID,ID_M1,ID_M2,ID_M3,ID_M4,nombre_masters,etat1,etat2,etat3,etat4,date_candidature,Lname,Fname,Fname_father,mother,sex,DOB,POB,Nat,ncivil,cir,building,street,region,nhood,tel_m,tel_f,email,Hschool,description,diploma1,desc_d1,diploma2,desc_d2,diploma3,desc_d3,motivation_m1,motivation_m2,motivation_m3,motivation_m4)
values(ID_C_seq.nextval,get_annee_scolaire,IDs,'O',ID_M1,ID_M2,ID_M3,ID_M4,nombre_masterss,'P','P','P','P',sysdate,Lname,Fname,Fname_father,mother,sex,DOB,POB,Nat,ncivil,cir,building,street,region,nhood,tel_m,tel_f,email,Hschool,description,diploma1,desc_d1,diploma2,desc_d2,diploma3,desc_d3,motivation_m1,motivation_m2,motivation_m3,motivation_m4);
exception
when no_data_found then
raise_application_error(-20017,'Vous n''etes pas un etudiant');
end;
/
This is the error message I am getting:
Errors for PROCEDURE OLD_CANDIDATE:
LINE/COL ERROR
-------- ---------------------------------------------
0/0 PLS-00801: internal error [phdite:node kind]
68/3 PL/SQL: SQL Statement ignored
69/110 PL/SQL: ORA-01775: looping chain of synonyms
72/4 PL/SQL: Statement ignored
I created some synonyms earlier and then dropped my tables and procedures and recreated them, I think this was the cause of the problem if I was not mistaken, can someone tell me how to fix this issue, or perhaps delete all synonyms? I tried dba_synonyms but I got that the table or view does not exist.

Related

PLS-00049: bad bind variable 'X_VARIABLE'

I'm getting the following error when I trying to get a record from a table, in this case, is (SERVICIOENDIAS)/SERVICETIMEINDAYS and I don't know why I'm getting that errr :
Trigger TRG_CONTROL_SERVICIO compiled
LINE/COL ERROR
--------- -------------------------------------------------------------
20/11 PLS-00049: bad bind variable 'NEW.V_SERVICIODIAS'
Errors: check compiler log
I'm a dummy with Oracle and possibly I may do a lot of mistakes and bad practices, so I'll appreciate it if you can say me that.
CREATE OR REPLACE TRIGGER TRG_CONTROL_SERVICIO
BEFORE
INSERT OR UPDATE
ON SERVICIO
FOR EACH ROW
DECLARE
V_SERVICIODIAS INT;
CURSOR C_SERVICIODIAS IS
SELECT TIEMPOSERVICIODIAS INTO V_SERVICIODIAS
FROM SERVICIO;
BEGIN
FOR R_SERVICIODIAS IN C_SERVICIODIAS LOOP
IF INSERTING THEN
IF :NEW.FECHAREGISTRO > SYSDATE THEN
LOG_AUDIT( USER,
SYSDATE,
'SERVICIO',
'INSERT FECHA INCORRECTA',
'SE EJECUTO EL TRG_CONTROL_SERVICIO');
RAISE_APPLICATION_ERROR(-20000, 'FECHA INCORRECTA, INTENTE DE NUEVO');
ELSE
DBMS_OUTPUT.PUT_LINE('INSERTANDO UN SERVICIO');
END IF;
IF :NEW.V_SERVICIODIAS <= 60 THEN
DBMS_OUTPUT.PUT_LINE('INSERTANDO UN SERVICIO');
ELSE
LOG_AUDIT( USER,
SYSDATE,
'SERVICIO',
'NO SE PUEDE UN SERVICIO MAYOR A 60 DIAS',
'SE EJECUTO EL TRG_CONTROL_SERVICIO');
RAISE_APPLICATION_ERROR(-20000, 'NO SE PUEDE REGISTRAR EL SERVICIO, MUCHAS HORAS',TRUE);
END IF;
ELSIF UPDATING THEN
IF :NEW.FECHAREGISTRO <> :OLD.FECHAREGISTRO AND :NEW.FECHAREGISTRO > SYSDATE THEN
LOG_AUDIT( USER,
SYSDATE,
'SERVICIO',
'PROHIBIDO UPDATE FECHAREGISTRO',
'SE EJECUTO EL TRG_CONTROL_SERVICIO');
RAISE_APPLICATION_ERROR(-20000, 'FECHA INCORRECTA, NO SE PUEDE MODIFICAR ESTA FECHA',TRUE);
ELSE
DBMS_OUTPUT.PUT_LINE('ACTUALIZANDO UN EMPLEADO');
END IF;
END IF;
END LOOP;
END;
In your program V_SERVICIODIAS INT; is a declared variable, so you have to use it syntactically as a variable.
The correct if statement is the following, please try to use it:
IF V_SERVICIODIAS <= 60 THEN
As has been pointed out, V_SERVICIODIAS is a local variable so it's not part of the :NEW pseudorecord. You'd use
IF V_SERVICIODIAS <= 60 THEN
Once you do that, the next issue is that nothing is actually populating that local variable so the if statement can never be true. That's because there is a syntax error in your cursor definition. You use an into clause if you have a select statement that returns a single row not when you're defining a cursor that you plan on looping over
CURSOR C_SERVICIODIAS IS
SELECT TIEMPOSERVICIODIAS
FROM SERVICIO;
Once you fix the cursor definition error, you'd get rid of the local variable entirely and just reference the column from the cursor.
IF R_SERVICIODIAS.TIEMPOSERVICIODIAS <= 60 THEN
Having done all that, however, you're going to encounter a mutating table runtime error because a row-level cursor on the SERVICIO isn't going to be able to query the SERVICIO table. And, unfortunately, at that point it's not obvious how to resolve the problem because it's not obvious why the cursor exists in the first place. Why would you want to loop over every row in the table every time you insert a new row into the table? That doesn't really make any sense.
One possibility is that you don't actually want to loop over every row in the table. Perhaps you want to remove the V_SERVICIODIAS local variable and the cursor definition and the loop and just reference the TIEMPOSERVICIODIAS from the current row.
IF :NEW.TIEMPOSERVICIODIAS <= 60 THEN

How can I fix this package body creation error?

I'm making a package to collect some functions in the same place. But while I attempt to create the body it always has an error.
I have tried everything I know, but it doesn´t matter how much do I try it always gives me the same error
This is my package which does not bring me any error.
create or replace PACKAGE talde_paquete AS
procedure editaldeak(Equipo Taldeak.Kod_taldea%TYPE, Nombre Taldeak.izena%TYPE, Localidad Taldeak.Herria%TYPE, Correo taldeak.helbide_elektronikoa%TYPE,Campo Taldeak.Zelaia%TYPE);
procedure equipopartidos(Equipo partidak.talde1%TYPE);
END talde_paquete;
And this is my package body which is the one who brings me always the same error
CREATE OR REPLACE PACKAGE BODY talde_paquete
IS
procedure editaldea(Equipo Taldeak.Kod_taldea%TYPE, Nombre Taldeak.izena%TYPE, Localidad Taldeak.Herria%TYPE, Correo taldeak.helbide_elektronikoa%TYPE,Campo Taldeak.Zelaia%TYPE)
AS
VTaldea NUMBER(1);
Taldenoexist EXCEPTION;
BEGIN
SELECT COUNT(Kod_Taldea) INTO VTaldea FROM Taldeak WHERE Kod_Taldea=Equipo;
IF VTaldea=1 THEN
UPDATE Taldeak SET Izena=Nombre, Herria=Localidad, Helbide_Elektronikoa=Correo, Zelaia=Campo WHERE Kod_taldea=Equipo;
ELSE
RAISE Taldenoexist;
END IF;
EXCEPTION
WHEN Taldenoexist THEN
DBMS_OUTPUT.PUT_LINE('Taldea ez da existitzen');
END editaldea;
procedure equipopartidos(Equipo partidak.talde1%TYPE)
IS
CURSOR PartidoEquipo IS
SELECT Talde1, Talde2, P_Data FROM Partidak WHERE Talde1 LIKE Equipo OR Talde2 LIKE Equipo;
E1 Partidak.Talde1%TYPE;
E2 Partidak.Talde2%TYPE;
Fecha Partidak.P_Data%TYPE;
existe NUMBER(3);
Taldexist EXCEPTION;
BEGIN
SELECT COUNT(Talde1) INTO existe FROM partidak WHERE Talde1=Equipo OR Talde2=Equipo;
IF (existe>0)THEN
OPEN PartidoEquipo;
FETCH PartidoEquipo INTO E1,E2,Fecha;
WHILE PartidoEquipo%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(E1||' taldeak '||E2||' taldearen aurka jokatuko du '||Fecha);
FETCH PartidoEquipo INTO E1,E2,Fecha;
END LOOP;
CLOSE PartidoEquipo;
ELSE
RAISE Taldexist;
END IF;
EXCEPTION
WHEN Taldexist THEN
DBMS_OUTPUT.PUT_LINE('Taldea ez da existitzen');
END equipopartidos;
END talde_paquete;
/
And here is the error that I get when I'm attempting to run the body script.
LINE/COL ERROR
--------- -------------------------------------------------------------
0/0 PL/SQL: Compilation unit analysis terminated
1/14 PLS-00905: object BIZKAIABASKET.TALDE_PAQUETE is invalid
1/14 PLS-00304: cannot compile body of 'TALDE_PAQUETE' without its specification
Errors: check compiler log
#hotfix is absolutely right, the error message when compiling is quite clear. The definition of the procedures in the body must be the same as the one defined in the header, I notice that there is a difference in the name editaldeak vs editaldea

How to dbms_output.put_line in Oracle

The result doesn't show the command ROUND(SYSDATE - V_FECHA,1) by dbms_output.put_line, I have this script:
SET SERVEROUTPUT ON
DECLARE
v_fecha v$database.created%TYPE;
BEGIN
CASE
WHEN ( SYSDATE - v_fecha <= 50 ) THEN
dbms_output.put_line('LA FECHA DE CREACION DE LA BASE DE DATOS ES <= 50 DÍAS');
WHEN ( SYSDATE - v_fecha > 50 AND SYSDATE - v_fecha <= 100 ) THEN
dbms_output.put_line('LA FECHA DE CREACIÓN ES MAYOR QUE 50 DÍAS O <= 100 DÍAS');
ELSE
dbms_output.put_line('LA FECHA DE CREACIÓN ES IGUAL A '
|| round(SYSDATE - v_fecha,1)
|| ' DÍAS');
END CASE;
END;
/
OUTPUT:
LA FECHA DE CREACIÓN ES IGUAL A DÍAS.
Oracle Version: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
IDE: SQL DEVELOPER - Versión 4.1.1.19
Thanks.
The output of the command ROUND(SYSDATE - V_FECHA,1) is not shown, because V_FECHA is still NULL in your code. You can verify that with
SELECT ROUND(SYSDATE - NULL) FROM DUAL;
which doesn't show anything, too. Nearly every operation in SQL will output NULL if the input contains NULL values, and DBMS_OUTPUT shows then an empty string.
As #Kaushik suggested, if you add the SELECT to your code, and maybe something that catches NULL values, everything should be fine:
DECLARE
v_fecha v$database.created%TYPE;
delta NUMBER;
BEGIN
SELECT created INTO v_fecha FROM v$database;
delta := v_fecha - SYSDATE;
CASE WHEN delta <= 50 THEN
dbms_output.put_line('LA FECHA DE CREACION DE LA BASE DE DATOS ES <= 50 DÍAS');
WHEN delta > 50 AND delta <= 100 THEN
dbms_output.put_line('LA FECHA DE CREACIÓN ES MAYOR QUE 50 DÍAS O <= 100 DÍAS');
WHEN delta IS NULL THEN
dbms_output.put_line('LA FECHA DE CREACIÓN ES DESCONOCIDA');
ELSE
dbms_output.put_line('LA FECHA DE CREACIÓN ES IGUAL A '
|| NVL(round(SYSDATE - v_fecha,1), 0)
|| ' DÍAS');
END CASE;
END;
/
I put in two options, WHEN delta IS NULL and NVL to show you different possibilities.
Furthermore I try to call SYSDATE only once, as every call of SYSDATE might be slightly later than the previous one. (The difference is of course very little, but I am trying to prevent errors which occur very rarely but are then very difficult to find.)
You probably want to fetch from v$database. Add this after BEGIN
SELECT
created
INTO v_fecha
FROM
v$database;

ORA-01403 no data found in trigger execution

I have a problem here with a trigger. The purpose of the trigger is to verify that the client associated with a car registration, paid or not paid the bill in a workshop. If the client has paid all, then it is created a new service order (so far runs), but then paid the account is not possible to create a work order. So here the problem arises when I try to insert a service.
This is what's causing the trigger to fire:
INSERT INTO ORDEM(cod_ordem,data,codigo_func_m,tipo_ordem,matricula,estado_ordem)
VALUES(to_char(seq_cod_ordem.nextval),to_date('23/11/2014','dd/mm/yyyy'),'2','Serviço','66-AB-00','Pendente')
and I get this error after the execution:
Error starting at line : 140 in command -
INSERT INTO ORDEM(cod_ordem,data,codigo_func_m,tipo_ordem,matricula,estado_ordem)
VALUES(to_char(seq_cod_ordem.nextval),to_date('23/11/2014','dd/mm/yyyy'),'2','Serviço','66-AB-00','Pendente')
Error report -
SQL Error: ORA-01403: não foram encontrados dados
ORA-06512: na "BD1415_DC5.SALDO_CLIENTE_OFICINA", linha 7
ORA-04088: erro durante a execução do trigger 'BD1415_DC5.SALDO_CLIENTE_OFICINA'
01403. 00000 - "no data found"
*Cause:
*Action:
This is my code:
create or replace TRIGGER saldo_cliente_Oficina
BEFORE INSERT ON ORDEM
FOR EACH ROW
DECLARE
t_codigo_cliente CLIENTES.codigo_cliente%TYPE;
t_estado BOOLEAN := TRUE;
t_excecao EXCEPTION;
BEGIN
SELECT DISTINCT codigo_cliente INTO t_codigo_cliente
FROM ORDEM, VEICULO
WHERE (ORDEM.matricula = :NEW.matricula) AND (ORDEM.matricula = VEICULO.matricula);
FOR t_estado_fact IN (SELECT FACTURA.numero_factura,FACTURA.codigo_cliente,FACTURA.estado FROM FACTURA,CLIENTES
WHERE CLIENTES.codigo_cliente = t_codigo_cliente AND CLIENTES.codigo_cliente = FACTURA.codigo_cliente)LOOP
IF t_estado_fact.estado = 'Não Paga' THEN
t_estado := FALSE;
END IF;
IF t_estado = FALSE THEN
RAISE t_excecao;
END IF;
END LOOp;
EXCEPTION
WHEN t_excecao THEN
RAISE_APPLICATION_ERROR(-20001, 'O Proprietário do veiculo que pretende criar uma ordem, deve serviços a Oficina.');
END saldo_cliente_Oficina;
The below select in the trigger is returning no rows.In this case the first insert in ORDEM for a particular matricula will always fail.
SELECT DISTINCT codigo_cliente INTO t_codigo_cliente
FROM ORDEM, VEICULO
WHERE (ORDEM.matricula = :NEW.matricula) AND (ORDEM.matricula = VEICULO.matricula);
Kindly try changing this to the below
SELECT DISTINCT codigo_cliente INTO t_codigo_cliente
FROM VEICULO
WHERE VEICULO.matricula=:NEW.matricula;

Cursor in PL/SQL, my procedure doesnt work

i have a problem in my procedure...in this case i want to raisy the salary to employees(Empleado) that have been working 5 years or more inn the store "Bodega"(...sorry about my english,i speak spanish XD).
First, i was thinking about select the ID's of all the employees that satisfy the condition (in a cursor) and then compare them to the ID'S in the EMPLEADO TABLE, if the same(the ID'S) then UPDATE the salary...it doesn't work with the IF - END IF (i put in COMMENTS) but without it.
needing help...i am doing something wrong but dont know what it is.
CREATE OR REPLACE PROCEDURE aumento_empleado(idBodega IN CHAR)IS
CURSOR c_empl IS SELECT E.idEmpleado
FROM Empleado E, Bodega B
WHERE( MONTHS_BETWEEN(sysdate,E.fecha_contrato)>=5*12
AND E.id_Bodega=B.id_Bodega
AND B.id_Bodega=idBodega);
idEmpl Char(8);
NO_EMP EXCEPTION;
BEGIN
OPEN c_empl;
LOOP
FETCH c_empl INTO idEmpl;
EXIT WHEN c_empl%notfound;
IF c_empl%ROWCOUNT=0 THEN
RAISE NO_EMP;
END IF;
--IF (idEmpl=Empleado.idEmpleado) THEN
UPDATE Empleado
SET Empleado.Sueldo=Empleado.Sueldo + Empleado.Sueldo*0.05;
--END IF;
END LOOP;
CLOSE c_empl;
EXCEPTION
WHEN NO_EMP THEN
dbms_output.put_line('No hay empleados que cumplan con las condiciones pedidas para la bonificacion' ) ;
WHEN OTHERS THEN
dbms_output.put_line('Error: hubo un error durante la ejecucion del procedimiento' ) ;
END aumento_empleado;
This single statement should work for your purpose
UPDATE Empleado E
SET E.Sueldo=E.Sueldo + E.Sueldo*0.05
WHERE MONTHS_BETWEEN(sysdate,E.fecha_contrato)>=5*12
AND E.id_Bodega IN (SELECT B.id_Bodega FROM Bodega B)
Avoid using loops where they are not absolutely required.

Resources