Oracle – Create a function that has the system date as a default parameter that returns all rows meeting a certain condition on the parameter

huangapple go评论71阅读模式
英文:

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));

huangapple
  • 本文由 发表于 2023年2月24日 05:20:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75550431.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定