SQL sólo puede utilizar las funciones de la proyección: se necesita algo que devuelve un valor. Entonces vas a tener que escribir algunas funciones. Esa es la mala noticia. La buena noticia es que puede reutilizar toda la inversión en sus procedimientos almacenados.
Aquí hay un procedimiento que impone una regla comercial completamente equitativa: solo los gerentes pueden tener un salario alto.
SQL> create or replace procedure salary_rule
2 (p_sal in emp.sal%type
3 , p_job in emp.job%type)
4 is
5 x_sal exception;
6 begin
7 if p_sal > 4999 and p_job != 'MANAGER' then
8 raise x_sal;
9 end if;
10 exception
11 when x_sal then
12 raise_application_error(-20000, 'Only managers can earn that much!');
13 end salary_rule;
14/
Procedure created.
SQL>
Como es un procedimiento, no podemos usarlo en una instrucción SELECT; tenemos que envolverlo en una función. Esta función solo llama al procedimiento almacenado. Devuelve el parámetro de entrada P_SAL. En otras palabras, si el salario es válido (de acuerdo con las reglas) será devuelto. De lo contrario, la función volverá a lanzar la excepción del procedimiento almacenado.
SQL> create or replace function validate_salary
2 (p_sal in emp.sal%type
3 , p_job in emp.job%type)
4 return emp.sal%type
5 is
6 begin
7 salary_rule(p_sal, p_job);
8 return p_sal;
9 end validate_salary;
10/
Function created.
SQL>
La función tiene que devolver un valor que queremos insertar en nuestra tabla. No puede devolver una frase sin sentido como "salario correcto". Además, si queremos validar dos columnas, necesitamos una función separada para cada una, incluso si existe una relación entre ellas y usamos el mismo procedimiento almacenado para validar ambas. Buen uso de la palabra clave DETERMINISTIC.
Aquí está la prueba: fontaneros no pueden ganar 5000 spondulicks ....
SQL> insert into emp
2 (empno
3 , ename
4 , job
5 , deptno
6 , sal)
7 select
8 emp_seq.nextval
9 , 'HALL'
10 , 'PLUMBER'
11 , 60
12 , validate_salary(5000, 'PLUMBER')
13 from dual
14/
, validate_salary(5000, 'PLUMBER')
*
ERROR at line 12:
ORA-20000: Only managers can earn that much!
ORA-06512: at "APC.SALARY_RULE", line 12
ORA-06512: at "APC.VALIDATE_SALARY", line 7
SQL>
... pero los administradores pueden (porque se lo merecen):
SQL> insert into emp
2 (empno
3 , ename
4 , job
5 , deptno
6 , sal)
7 select
8 emp_seq.nextval
9 , 'HALL'
10 , 'MANAGER'
11 , 60
12 , validate_salary(5000, 'MANAGER')
13 from dual
14/
1 row created.
SQL>
Tenga en cuenta que la excepción lanzada es crucial para este trabajo.No podemos escribir algo raro SI EL SALARIO ES VÁLIDO Y LUEGO INSERTAR la lógica en nuestra declaración de SQL. Por lo tanto, si el procedimiento almacenado no genera una excepción sino que devuelve un estado de error débil, la función de ajuste tendrá que interpretar la salida y arrojar su propia excepción.
Es lo que necesito. Gracias. –