Agregar muchas funciones de validación (UDF) a Oracle: qué método se ejecuta más rápido
Tengo que mover más de 50 funciones de validación a Oracle. Estoy buscando el enfoque que funciona más rápido, pero también me gustaría sortear unboolean
emitir si es posible. El objeto de devolución para todos ellos debe ser el mismo para que la aplicación pueda reaccionar ante el resultado de manera consistente y alertar al usuario o mostrar cualquier mensaje emergente que necesitemos. Creé unvalObj
para esto, pero aún no estoy seguro si ese es el mejor enfoque. El formato de retorno se puede cambiar porque el front-end que reacciona fuera de él aún no está desarrollado. Al final, contendrá muchas funciones de validación diferentes, desde entero, número, teléfono, correo electrónico, IPv4, IPv6, etc. Esto es lo que tengo hasta ahora ...
/***
This is the validation object.
It stores 1 for valid, 0 for not valid and some helper text that can be relayed back to the user.
***/
create or replace type valObj as object (
result number(1),
resultText varchar(32000)
);
/***
Coming from ColdFusion this seems clean to me but the function
will end up being a couple thousand lines long.
***/
create or replace function isValid(v in varchar2, format in varchar2)
return valObj
is
test number;
begin
if format = 'number' then
begin
test := to_number(v);
return valObj(1,null);
exception when VALUE_ERROR then return valObj(0,'Invalid number. Valid formats are: 12345, 12345.67, -12345, etc...');
end;
elsif format = 'integer' then
null; --TO DO
elsif format = 'email' then
null; --TO DO
elsif format = 'IPv4' then
null; --TO DO
elsif format = 'IPv6' then
null; --TO DO
end if;
--dozens of others to follow....
end;
/
/* Example Usage in SQL */
select isValid('blah','number') from dual; -- returns: (0, Invalid number. Valid formats are: 12345, 12345.67, -12345, etc...)
select isValid('blah','number').result from dual; -- returns: 0
select isValid('blah','number').resulttext from dual; -- returns: Valid formats are: 12345, 12345.67, -12345, etc...
select isValid(1234567890.123,'number') from dual; -- returns: 1,{null}
select isValid(1234567890.123,'number').result from dual; -- returns: 1
select isValid(1234567890.123,'number').resulttext from dual; -- returns: {null}
/* Example Usage in PL/SQL */
declare
temp valObj;
begin
temp := isValid('blah','number');
if (temp.result = 0) then
dbms_output.put_line(temp.resulttext);
else
dbms_output.put_line('Valid');
end if;
end;
/
Mis preguntas son:
Cuando lo use en PL / SQL, me encantaría poder hacerboolean
comprueba así:if (temp.result) then
pero no puedo encontrar una manera, porque eso no funcionará en SQL. ¿Debo agregar un tercer atributo booleano alvalObj
o hay otra forma que no conozco?Estas funciones de validación podrían terminar siendo llamadas dentro de bucles grandes. Sabiendo eso, ¿es esta la forma más eficiente de lograr estas validaciones?Agradecería cualquier ayuda. ¡Gracias!
ACTUALIZAR: Me olvidé deMEMBER FUNCTIONS
. Gracias @Brian McGinity por recordármelo. Así que me gustaría seguir con este método ya que mantiene eltype
y esfunctions
encapsulados juntos¿Habría alguna diferencia de velocidad entre este método y una función independiente? ¿Sería esto compilado y almacenado lo mismo que una función independiente?
create or replace type isValid as object (
result number(1),
resulttext varchar2(32000),
constructor function isValid(v varchar, format varchar) return self as result );
/
create or replace type body isValid as
constructor function isValid(v varchar, format varchar) return self as result as
test number;
begin
if format = 'number' then
begin
test := to_number(v);
self.result := 1;
self.resulttext := null;
return;
exception when VALUE_ERROR then
self.result := 0;
self.resulttext := 'Invalid number. Valid formats are: 12345, 12345.67, -12345, etc...';
return;
end;
elsif format = 'phone' then
null; --TO DO
end if;
--and many others...
end;
end;
/
/* Example Usage in SQL */
select isValid('a','number') from dual;
/* Example Usage in PL/SQL */
declare
begin
if (isValid('a','number').result = 1) then
null;
end if;
end;
/
RESULTADOS DE LA PRUEBA:
/* Test isValid (the object member function), this took 7 seconds to run */
declare
begin
for i in 1 .. 2000000 loop
if (isValid('blah','number').result = 1) then
null;
end if;
end loop;
end;
/* Test isValid2 (the stand-alone function), this took 16 seconds to run */
declare
begin
for i in 1 .. 2000000 loop
if (isValid2('blah','number').result = 1) then
null;
end if;
end loop;
end;
AmbosisValid
yisValid2
hacer el mismo código exacto, solo corren esta líneatest := to_number(v);
luego haga la excepción si falla y devuelve el resultado. ¿Esto parece ser una prueba válida? ¿El método de la función miembro Object es realmente más rápido que una función independiente?