|
我必须将大约50多个验证功能转移到Oracle中间。我正在寻找最快的方法,但我也希望boolean尽可能解决一个问题。它们的返回对象都必须相同,以便应用程序可以一致的方式对结果做出反应,并警告用户或显示我们可能需要的任何弹出窗口,消息。我valObj为此创建了一个,但我不确定这是否是最好的方法。返回格式可以改变,因为尚未响应的前端尚未开发。最后,它将包许多不同的验证功能,包括整数、数字、电话、电子邮件、IPv4,IPv等等。这是我到目前为止所拥有的。…
! J3 R5 A" L" K! ?' g/***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 functionwill end up being a couple thousand lines long.***/create or replace function isValid(v in varchar2,format in varchar2)return valObjis test number;beginif 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 DOelsif format = 'email' then null; --TO DOelsif format = 'IPv4' then null; --TO DOelsif format = 'IPv6' then null; --TO DOend 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: 0select 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: 1select isValid(1234567890.123,'number').resulttext from dual; -- returns: {null}/* Example Usage in PL/SQL */declaretemp 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;/我的问题是:
4 E+ @2 j9 b! N! x* ^) I; G[ol]在PL / SQL当它被使用时,我希望它能被使用。boolean这样检查:if (temp.result) then但是我不知道一种方法,因为它在SQL不起作用。第三个布尔属性应该只添加到中间,valObj还是我不知道另一种方法?. j4 N' x/ e# _- w: I; G
这些验证功能最终可能在大循环中调用。你知道,这是完成这些验证的最有效方法吗?[/ol]非常感谢! n. q* C8 D+ X
更新: 我忘记了MEMBER FUNCTIONS。感谢@Brian2 y5 ]8 c9 }# g3 a. C8 d' y& ?
McGinity提醒我。所以,我想用这个方法,因为它会type和及其functions一起包装。这种方法和独立功能之间会有速度差异吗?# s2 C7 J x2 U7 q3 `7 K4 S$ `6 \
它能像独立函数一样编译和存储吗?
' ~. I/ y; t J! U+ Z3 Jcreate 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 */declarebegin if (isValid('a','number').result = 1) then null; end if;end;/试验结果:# }- k D! _8 W6 I" n2 G5 h0 ?; m- {
/* Test isValid (the object member function),this took 7 seconds to run */declarebegin 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 */declarebegin for i in 1 .. 2000000 loop if (isValid2('blah','number').result = 1) then null; end if; end loop;end;双方isValid并isValid2完全相同的代码,他们只是跑这条线test :=to_number(v);然后执行异常,如果失败,返回结果。这似乎是一个有效的测试吗?事实上,对象成员函数的方法比独立函数快?
7 ]+ c; D. ^) \7 V T
( ]1 S! @8 E. s% I' }1 I 解决方案: & b8 I2 M6 P5 U9 {
如果将独立功能设置为DETERMINISTIC,而且数据重复性高,独立功能会更快。在我的机器上,这个设置将运行时间从9秒减少到0.1秒。由于某些原因,我不明白设置不能提高对象功能的性能。 K; g( E4 s9 Y6 m" a
create or replace function isValid2(v in varchar2,format in varchar2)return valObjdeterministic --<< Hit the turbo button!is test number;beginif 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; |
|