英文:
Oracle - Create a function that has the system date as a default parameter that returns all rows meeting a certain condition on the parameter
问题
在Oracle中,我有一个包含多个列的表,其中有两个日期列。我想要创建一个参数化函数,其中根据输入的日期,我想返回所有输入日期位于这两个日期列之间的行。此外,如果用户未传递输入日期 - 我必须使用系统日期作为默认参数。
我尝试创建一个管道函数来实现这一点,但是当我尝试使用if条件时,例如
create or replace function abc (v_date in date) return table_type pipelined;
begin
if v_date is null then
for row in (select a, b, c from abc where sysdate between abc.date1 and abc.date2) LOOP
pipe row(table_type(a, b, c));
else
for row in (select a, b, c from abc where v_date between abc.date1 and abc.date2) LOOP
pipe row(table_type(a, b, c));
end if;
end loop;
return;
我尝试过各种变体,但我不断收到错误消息,比如 - 找到else,期望end。
英文:
In oracle I have a table that has multiple columns, two of which are date columns. I want to create a parameterized function where given an input date I would like to return all the rows where the input date is between the two date columns. In addition, if the user doesn't pass an input - I have to use system date as the default parameter.
I've tried to create a pipelined function to do this, however when I try to use an if condition such as
create or replace function abc (v_date in date) return table_type pipelined;
begin
if v_date is null then
for row in (select a, b, c from abc where sysdate between abc.date1, abc.date2) LOOP
pipe row(table_type(a, b, c));
else
for row in (select a, b, c from abc where v_date between abc.date1, abc.date2) LOOP
pipe row(table_type(a, b, c));
end if;
end loop;
return;
I've tried variations of this but I keep getting errors like - found else, expecting end.
答案1
得分: 2
这里是一个选项。
设置日期格式(您不必这样做):
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
示例表格:
SQL> select * from test;
ID DATE_FROM DATE_TO
---------- ---------- ----------
1 15.01.2022 18.02.2022
2 20.01.2022 30.01.2022
3 15.08.2022 31.08.2022
4 01.02.2023 28.02.2023
该函数接受日期参数,默认为截断的sysdate。它返回refcursor。
SQL> create or replace function f_test (par_datum in date default trunc(sysdate))
2 return sys_refcursor
3 is
4 rc sys_refcursor;
5 begin
6 open rc for select * from test
7 where par_datum between date_from and date_to;
8 return rc;
9 end;
10 /
Function created.
测试:没有参数时,使用sysdate:
SQL> select f_test from dual;
F_TEST
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
ID DATE_FROM DATE_TO
---------- ---------- ----------
4 01.02.2023 28.02.2023
传递参数值:
SQL> select f_test(date '2022-01-25') from dual;
F_TEST(DATE'2022-01-
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
ID DATE_FROM DATE_TO
---------- ---------- ----------
1 15.01.2022 18.02.2022
2 20.01.2022 30.01.2022
SQL>
英文:
Here's one option.
Setting date format (you don't have to do it):
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
Sample table:
SQL> select * from test;
ID DATE_FROM DATE_TO
---------- ---------- ----------
1 15.01.2022 18.02.2022
2 20.01.2022 30.01.2022
3 15.08.2022 31.08.2022
4 01.02.2023 28.02.2023
Function accepts date parameter which defaults to truncated sysdate. It returns refcursor.
SQL> create or replace function f_test (par_datum in date default trunc(sysdate))
2 return sys_refcursor
3 is
4 rc sys_refcursor;
5 begin
6 open rc for select * from test
7 where par_datum between date_from and date_to;
8 return rc;
9 end;
10 /
Function created.
Testing: with no parameter, sysdate is being used:
SQL> select f_test from dual;
F_TEST
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
ID DATE_FROM DATE_TO
---------- ---------- ----------
4 01.02.2023 28.02.2023
Passing parameter value:
SQL> select f_test(date '2022-01-25') from dual;
F_TEST(DATE'2022-01-
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
ID DATE_FROM DATE_TO
---------- ---------- ----------
1 15.01.2022 18.02.2022
2 20.01.2022 30.01.2022
SQL>
答案2
得分: 2
不需要使用 IF
,当你有 NVL
时... 但是你需要修复 BETWEEN
运算符,它期望一个 AND
,而不是逗号。
create or replace function abc (v_date in date) return table_type pipelined;
begin
for row in (select a, b, c from abc where NVL(v_date,sysdate) between abc.date1 AND abc.date2)
loop
pipe row(table_type(a, b, c));
end loop;
return;
end;
英文:
No need for IF
when you have NVL
... you do however need to fix the BETWEEN
operator which expects an AND
, not a comma.
create or replace function abc (v_date in date) return table_type pipelined;
begin
for row in (select a, b, c from abc where NVL(v_date,sysdate) between abc.date1 AND abc.date2)
loop
pipe row(table_type(a, b, c));
end loop;
return;
end;
答案3
得分: 1
只需使用coalesce,然后您就不需要if语句。
for row in (select a, b, c from abc where coalesce(v_date,sysdate) between abc.date1 and abc.date2) LOOP
pipe row(table_type(a, b, c));
英文:
Just use coalesce then you don't need the if statement
for row in (select a, b, c from abc where coalesce(v_date,sysdate) between abc.date1 and abc.date2) LOOP
pipe row(table_type(a, b, c));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论