Adicionando muitas funções de validação (UDFs) ao Oracle - qual método é executado mais rapidamente
Eu tenho que mudar mais de 50 funções de validação para o Oracle. Estou procurando a abordagem mais rápida, mas também gostaria de contornar umboolean
emitir se possível. O objeto de retorno para todos eles precisa ser o mesmo para que o aplicativo possa reagir de maneira consistente ao resultado e alertar o usuário ou exibir os pop-ups, mensagens que precisarmos. Eu criei umvalObj
para isso, mas ainda não tenho certeza se essa é a melhor abordagem. O formato de retorno pode ser alterado porque o front-end que reage dele ainda não foi desenvolvido. No final, ele conterá muitas funções de validação diferentes, de número inteiro, número, telefone, email, IPv4, IPv6, etc ... É isso que eu tenho até agora ...
/***
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;
/
Minhas perguntas são:
Ao usá-lo em PL / SQL, eu adoraria poder fazerboolean
verifica assim:if (temp.result) then
mas não consigo descobrir uma maneira, porque isso não funcionará no SQL. Devo apenas adicionar um terceiro atributo booleano aovalObj
ou existe outra maneira que eu não conheço?Essas funções de validação podem acabar sendo chamadas em loops grandes. Sabendo disso, essa é a maneira mais eficiente de realizar essas validações?Eu apreciaria qualquer ajuda. Obrigado!
ATUALIZAR: Eu esqueciMEMBER FUNCTIONS
. Obrigado @Brian McGinity por me lembrar. Então, eu gostaria de seguir esse método, pois mantém otype
e os seusfunctions
encapsulados juntos.Haveria alguma diferença de velocidade entre esse método e uma função autônoma? Isso seria compilado e armazenado da mesma forma que uma função autônoma?
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;
/
RESULTADO DOS TESTES:
/* 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
eisValid2
fazem o mesmo código exato, eles apenas rodam esta linhatest := to_number(v);
faça a exceção se falhar e retorne o resultado. Isso parece ser um teste válido? O método da função membro Object é realmente mais rápido que uma função autônoma ???