动态PL/SQL查询,如何忽略空参数?

发布于 2024-10-16 03:57:15 字数 505 浏览 1 评论 0原文

我有一个带有多个参数的 PL/SQL 过程。当 web 应用程序调用该过程时,如果它不使用某个参数,它就会将 is 作为 null 传递,即

procedure test (param1 in varchar2, param2 in varchar2, param3 in varchar2, cursor out sys_refcursor)
...
end procedure test;

我想进行一个 SQL 查询,仅当参数不为 null 时,我才在 WHERE 子句中包含给定的参数。除了在字符串中构建 SQL 查询然后打开该字符串的游标之外,有没有一种方法可以以优雅的方式实现此目的,如下所示

vSQL := 'SELECT * from TABLE WHERE something = something_else';
if param1 IS NOT NULL
    vSQL := vSQL || 'AND some_param = ' || param1;

I have a PL/SQL procedure with multiple parameters. When a webapp calls the procedure, if it's not using a certain parameter, it passes is as null, ie

procedure test (param1 in varchar2, param2 in varchar2, param3 in varchar2, cursor out sys_refcursor)
...
end procedure test;

I want to make an SQL query where I include the given parameters in the WHERE clause only if the parameter is not null. Is there a way to achieve this in an elegant way, other than building the SQL query in a string and then opening the cursor for that string, like this

vSQL := 'SELECT * from TABLE WHERE something = something_else';
if param1 IS NOT NULL
    vSQL := vSQL || 'AND some_param = ' || param1;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷鸟归林 2024-10-23 03:57:15

我在 dba.stackexchange.com 上回答了类似的问题

I have answered a similar question on dba.stackexchange.com

和我恋爱吧 2024-10-23 03:57:15

您可以将其全部编码为一个选择

SELECT * from TABLE WHERE something = something_else
AND ((param1 IS NOT NULL AND some_param = param1) OR 1)

You can code it all into a single select

SELECT * from TABLE WHERE something = something_else
AND ((param1 IS NOT NULL AND some_param = param1) OR 1)
海拔太高太耀眼 2024-10-23 03:57:15

创建一个测试表:

create table testtab
(
name_first varchar2(50),
name_last varchar2(50),
name_middle varchar2(50)
);

insert into testtab values ('Joe', 'Jones', 'A');
insert into testtab values ('Joe', 'Smith', 'A');
insert into testtab values ('Steve', 'Jones', 'B');
insert into testtab values ('Axl', 'Rose', 'C');
insert into testtab values ('Phil', 'McCracken', 'D');
commit;

创建您的过程:

CREATE OR REPLACE procedure ECDATA.get_testtab_rows
(i_name_first in varchar2 default null,
i_name_last in varchar2 default null,
i_name_middle in varchar2 default null,
o_cursor out sys_refcursor
) as

    v_result_cur    sys_refcursor;

begin

    open v_result_cur for
        select * from testtab
        where name_first like nvl(i_name_first, '%')
        and name_last like nvl(i_name_last, '%')
        and name_middle like nvl(i_name_middle, '%')
    ;

    o_cursor := v_result_cur;

end;
/

然后像这样调用它:

declare

    v_cur sys_refcursor;
    testtab_rec testtab%rowtype;

begin

    get_testtab_rows(i_name_last=>'Jones', o_cursor=>v_cur);
    loop

        fetch v_cur into testtab_rec;
        exit when v_cur%notfound;
        dbms_output.put_line(testtab_rec.name_first || ' ' || testtab_rec.name_middle || ' ' || testtab_rec.name_last);

    end loop;

exception
    when others then raise;
end;

Create a test table:

create table testtab
(
name_first varchar2(50),
name_last varchar2(50),
name_middle varchar2(50)
);

insert into testtab values ('Joe', 'Jones', 'A');
insert into testtab values ('Joe', 'Smith', 'A');
insert into testtab values ('Steve', 'Jones', 'B');
insert into testtab values ('Axl', 'Rose', 'C');
insert into testtab values ('Phil', 'McCracken', 'D');
commit;

Create your procedure:

CREATE OR REPLACE procedure ECDATA.get_testtab_rows
(i_name_first in varchar2 default null,
i_name_last in varchar2 default null,
i_name_middle in varchar2 default null,
o_cursor out sys_refcursor
) as

    v_result_cur    sys_refcursor;

begin

    open v_result_cur for
        select * from testtab
        where name_first like nvl(i_name_first, '%')
        and name_last like nvl(i_name_last, '%')
        and name_middle like nvl(i_name_middle, '%')
    ;

    o_cursor := v_result_cur;

end;
/

Then call it like this:

declare

    v_cur sys_refcursor;
    testtab_rec testtab%rowtype;

begin

    get_testtab_rows(i_name_last=>'Jones', o_cursor=>v_cur);
    loop

        fetch v_cur into testtab_rec;
        exit when v_cur%notfound;
        dbms_output.put_line(testtab_rec.name_first || ' ' || testtab_rec.name_middle || ' ' || testtab_rec.name_last);

    end loop;

exception
    when others then raise;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文