当前位置: 首页 > 面试题库 >

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

濮宇定
2023-03-14
问题内容

我必须将大约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;
/

我的问题是:

  1. 在PL / SQL中使用它时,我希望能够boolean像这样进行检查:if (temp.result) then但是我不知道一种方法,因为它在SQL中不起作用。我应该只向中添加第三个布尔属性,valObj还是我不知道另一种方法?
  2. 这些验证功能最终可能在大型循环中被调用。知道吗,这是完成这些验证的最有效方法吗?

我将不胜感激。谢谢!

更新: 我忘记了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;
/

试验结果:

/* 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;

双方isValidisValid2做完全相同的代码,他们只是跑这条线test := to_number(v);然后执行异常,如果它失败,并返回结果。这似乎是有效的测试吗?实际上,对象成员函数方法比独立函数要快???


问题答案:

如果将独立功能设置为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;
/


 类似资料:
  • 本文向大家介绍Vue中添加手机验证码组件功能操作方法,包括了Vue中添加手机验证码组件功能操作方法的使用技巧和注意事项,需要的朋友参考一下 什么是组件: 组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。 写在前面: 今天要实现的功

  • 问题内容: 我一直在寻找如何执行此操作,但到目前为止我还没有找到任何相关的东西,:(我可以嵌套两个函数,但是我只是想知道这是否可行吗? 目前我的JS代码: 我想一键调用两个函数,如何在angularJS中做到这一点?我认为当您添加多个类时会像在CSS中那样直接…但是不是:( 问题答案: 您有2个选择: 创建包装这两个方法的第三个方法。这样做的好处是可以减少模板中的逻辑。 否则,如果要在ng-cli

  • 我有一个非常简单的restful控制器,看起来像这样: 但是,现在我想为此添加一个搜索选项。圣杯是如何实现这一目标的? 我想补充以下内容: 但这使得Grails (2.3)崩溃(| Error编译时出现致命错误org . Apache . tools . ant . build exception:编译失败(使用- stacktrace查看完整跟踪))。 那么添加这个的正确方法是什么呢?我正在寻找

  • 我想添加只允许经过身份验证的用户在Jitsi会议中创建会议的功能。我看到了外部API的jwt参数、config.tokenAuthUrl和lib-jitsi-met令牌文档,但我对如何将它们放在一起感到非常困惑。 现在,我的工作流程如下: 用户通过自定义应用程序登录谷歌。 用户被重定向到一个新的Jitsi会议,使用从Google登录信息派生的jwt参数。 我遇到的问题是验证这个令牌,以及如何设置它

  • 问题内容: 我的PyQT QTextEdit遇到一个相当奇怪的问题。 当我从QLineEdit输入一个字符串时,它会添加它,但是说我输入另一个,第一个字符串就会消失,我认为那是因为我没有追加文本。 知道我该怎么做吗? 以下是相关代码: 和重要的 编辑 我发现我需要使用 问题答案: 该方法将替换所有当前文本,因此您只需要使用该方法即可。(请注意,这两种方法都会自动添加尾随换行符)。