回答

收藏

向Oracle添加许多(UDF)验证功能-哪种方法运行最快

技术问答 技术问答 238 人阅读 | 0 人回复 | 2023-09-14

我必须将大约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;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则