以日期作为参数的函数-Oracle 11g

时间:2018-08-25 11:49:14

标签: sql plsql

我正在尝试执行一个以DATE作为参数的函数(格式为'MM / DD / YYYY',但它返回null。

CREATE OR REPLACE FUNCTION func_date  (h_date IN DATE)
RETURN DATE
AS
    emp_hire_date DATE;
BEGIN
    FOR rec IN (
    SELECT hire_date INTO emp_hire_date FROM EMPLOYEES
    WHERE hire_date < h_date
    )
    LOOP
    RETURN emp_hire_date;
    END LOOP;
END;

SELECT func_date('01/01/1990') FROM DUAL; --this returns NULL value

因此,我测试了一个PL / SQL块进行检查,但是设置为DATE的VARIABLE无法打印。有人可以帮忙吗?谢谢!

DECLARE
    emp_hire_date DATE;
BEGIN
FOR RECORD IN (
    SELECT hire_date INTO emp_hire_date
    FROM employees
    WHERE hire_date < '01/01/1990') LOOP
    DBMS_OUTPUT.PUT_LINE('Hire date is:' || emp_hire_date);
    END LOOP;
END;
/

我知道该块有效,因为这是输出:

Hire date is:
Hire date is:
Hire date is:

PL / SQL过程成功完成。

3 个答案:

答案 0 :(得分:0)

使用To_Date

CREATE OR REPLACE FUNCTION func_date  (h_date IN DATE)
RETURN DATE
AS
    emp_hire_date DATE;
BEGIN
    FOR rec IN (
    SELECT hire_date INTO emp_hire_date FROM EMPLOYEES
    WHERE to_date(hire_date,'MM/dd/yyyy') < to_date(h_date,'MM/dd/yyyy')
    )
    LOOP
    RETURN emp_hire_date;
    END LOOP;
END;

答案 1 :(得分:0)

您编写的

代码没有多大意义,尽管编译,但它们以错误的方式处理事情。

不要在光标SELECT INTO循环内FOR。您不想使用本地声明的变量,而是将值存储在游标变量中-如果要使用循环。

尽管,当您获取某物(这是第一行)后立即返回一个值时,我根本不知道为什么要使用循环。

无论如何:这是一个模拟您的代码的示例,但是此示例返回一个值。我在Scott的架构上运行它,因此表名和列名与您的稍有不同。将此代码与您的代码进行比较。

SQL> alter session set nls_date_format = 'dd/mm/yyyy';

Session altered.

SQL> CREATE OR REPLACE FUNCTION func_date (h_date IN DATE)
  2    RETURN DATE
  3  AS                               -- no local variable declaration
  4  BEGIN
  5    FOR rec IN (SELECT hiredate    -- no INTO clause here
  6                FROM EMP
  7                WHERE hiredate < h_date
  8               )
  9    LOOP
 10      RETURN rec.hiredate;         -- return cursor variable value
 11    END LOOP;
 12  END;
 13  /

Function created.

SQL> SELECT func_date(to_date('01/01/1990', 'dd/mm/yyyy')) FROM DUAL;  -- pass DATE, not a string

FUNC_DATE(
----------
17/12/1980

SQL>

答案 2 :(得分:0)

@Littlefoot感谢您的输入。我能够根据您的代码成功编写该函数,但是我知道会有不止一个结果,因此我使用光标编写了一个块进行测试,并成功了。

DECLARE
    CURSOR c1 IS
        SELECT hire_date
        FROM employees
        WHERE hire_date < '01/01/1990';
    h_date DATE;
BEGIN
    OPEN c1;
    LOOP
    FETCH c1 INTO h_date;
    EXIT WHEN c1%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE('Hire date is: ' ||h_date);
    END LOOP;
    CLOSE c1;
END;

结果是:

Hire date is: 06/17/1987
Hire date is: 09/21/1989
Hire date is: 09/17/1987


PL/SQL procedure successfully completed.

然后根据我写的代码块,用光标创建函数:

CREATE OR REPLACE FUNCTION func_date (h_date IN DATE)
RETURN SYS_REFCURSOR
AS
    c1 SYS_REFCURSOR;
BEGIN
    OPEN c1 FOR
        SELECT hire_date
        FROM employees
        WHERE hire_date < h_date;
    LOOP
    EXIT WHEN c1%NOTFOUND;
    RETURN c1;
    END LOOP;
    CLOSE c1;
END;

调用函数并传递日期:

SELECT func_date('01/01/1990') FROM DUAL;

结果如下。并不是我真正想要的,但我想我很快就能弄清楚如何将结果输出为记录

image