gfr*_*ius 6 sql oracle validation plsql
我必须将大约50多个验证函数移到Oracle中.我正在寻找运行速度最快的方法,但boolean如果可能的话,我也想解决一个问题.它们的返回对象都需要相同,以便应用程序可以以一致的方式对结果做出反应并提醒用户或显示我们可能需要的任何弹出窗口和消息.我valObj为此创建了一个,但不确定这是否是最好的方法.可以更改返回格式,因为尚未开发出响应它的前端.最后,它将包含许多不同的验证功能,从整数,数字,电话,电子邮件,IPv4,IPv6等...这是我到目前为止...
/***
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;
/
Run Code Online (Sandbox Code Playgroud)
我的问题是:
boolean检查:if (temp.result) then但是我找不到方法,因为这在SQL中不起作用.我应该只添加第三个布尔属性,valObj还是有另一种我不知道的方式?我很感激任何帮助.谢谢!
更新:我忘记了MEMBER FUNCTIONS.谢谢@Brian McGinity提醒我.所以我想使用这种方法,因为它保持type和它functions封装在一起. 这种方法和独立功能之间会有任何速度差异吗?它是否会作为独立函数编译和存储?
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;
/
Run Code Online (Sandbox Code Playgroud)
检测结果:
/* 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;
Run Code Online (Sandbox Code Playgroud)
双方isValid并isValid2做完全相同的代码,他们只是跑这条线test := to_number(v);然后执行异常,如果它失败,并返回结果.这似乎是一个有效的测试?Object成员函数方法实际上比独立函数更快???
如果将其设置为 DETERMINISTIC 并且数据高度重复,则独立函数会更快。在我的机器上,此设置将运行时间从 9 秒减少到 0.1 秒。由于我不明白的原因,设置不会提高对象函数的性能。
create or replace function isValid2(v in varchar2, format in varchar2)
return valObj
deterministic --<< Hit the turbo button!
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;
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)