我试图在oracle中编写UDF,根据提供的日期和今天之间的差异返回一些。以下是我的代码
SELECT FN_AGE_RANGE('01.01.2017') FROM DUAL;
CREATE OR REPLACE FUNCTION FN_AGE_RANGE(
SAP_DATE IN VARCHAR2 )
RETURN VARCHAR2
IS
ResultVar VARCHAR2(255);
TheDate DATE;
TheDiff NUMBER;
BEGIN
--convert to date
SELECT
CASE
WHEN SAP_DATE = '00.00.0000'
THEN NULL
ELSE to_date(SAP_DATE,'dd.mm.yyyy')
END
INTO TheDate
FROM DUAL;
--workout date difference
SELECT sysdate - TheDate
INTO TheDiff
FROM DUAL;
--set the frequency
SELECT
CASE
WHEN TheDiff < -180
THEN '>6 Months'
WHEN TheDiff < -90
THEN '3-6 Months'
WHEN TheDiff < 0
THEN '<3 Months'
END
INTO ResultVar
FROM DUAL;
RETURN(ResultVar);
END;
答案 0 :(得分:2)
代码
(sysdate - TheDate)
是积极的,所以
SELECT
CASE
WHEN TheDiff < -180
THEN '>6 Months'
WHEN TheDiff < -90
THEN '3-6 Months'
WHEN TheDiff < 0
THEN '<3 Months'
END
INTO ResultVar
FROM DUAL;
总是会返回null
将代码的最后一部分更改为此
SELECT
CASE
WHEN TheDiff > -180
THEN '>6 Months'
WHEN TheDiff > -90
THEN '3-6 Months'
WHEN TheDiff > 0
THEN '<3 Months'
END
INTO ResultVar
FROM DUAL;
答案 1 :(得分:1)
Vecchiasignora的回答与您的代码逻辑正确相关。但是,我想添加它来运行case语句,你不需要SQL,你也可以在PL / SQL中使用该构造。这样可以简化您的代码。
CREATE OR REPLACE FUNCTION FN_AGE_RANGE(
SAP_DATE IN VARCHAR2 )
RETURN VARCHAR2
IS
ResultVar VARCHAR2(255);
TheDate DATE;
TheDiff NUMBER;
BEGIN
--convert to date
CASE
WHEN SAP_DATE = '00.00.0000' THEN NULL;
ELSE TheDate := to_date(SAP_DATE,'dd.mm.yyyy');
END CASE;
--workout date difference
TheDiff := sysdate - TheDate;
--set the frequency
CASE
WHEN TheDiff > 180 THEN ResultVar := '>6 Months';
WHEN TheDiff > 90 THEN ResultVar := '3-6 Months';
WHEN TheDiff > 0 THEN ResultVar := '<3 Months';
END CASE;
RETURN(ResultVar);
END;
答案 2 :(得分:0)
确保您的案例陈述涵盖您的样本集
首先,SAP_DATE
的显着值似乎是SYSDATE
大于SAP_DATE
时。
例如,当我们有2016年11月1日的日期时,SAP_DATE
的年龄应为6个月。
当SAP_DATE
大于当前日期时,未定义ResultVar
。我将其称为“当前”。
在Oracle中使用case语句时,重要的是要考虑正在执行短路评估,因此第一个布尔表达式为true将是分配给ResultVar
的结果值。
以下是我的修改:
SCOTT@dev>set echo on;
SCOTT@dev>CREATE OR REPLACE FUNCTION FN_AGE_RANGE(
2 SAP_DATE IN VARCHAR2 )
3 RETURN VARCHAR2
4 IS
5 ResultVar VARCHAR2(255);
6 TheDate DATE;
7 TheDiff NUMBER;
8 BEGIN
9 --convert to date
10 SELECT
11 CASE
12 WHEN SAP_DATE = '00.00.0000'
13 THEN NULL
14 ELSE to_date(SAP_DATE,'dd.mm.yyyy')
15 END
16 INTO TheDate
17 FROM DUAL;
18 --workout date difference
19 SELECT sysdate - TheDate
20 INTO TheDiff
21 FROM DUAL;
22 --set the frequency
23 SELECT
24 CASE
25 WHEN TheDiff > 180
26 THEN '>6 Months'
27 WHEN TheDiff > 90
28 THEN '3-6 Months'
29 WHEN TheDiff > 0
30 THEN '<3 Months'
31 WHEN TheDiff <= 0
32 THEN 'Current'
33 ELSE NULL
34 END
35 INTO ResultVar
36 FROM DUAL;
37 RETURN(ResultVar);
38 END;
39 /
Function FN_AGE_RANGE compiled
SCOTT@dev>---sample data
SCOTT@dev>-- > 6 months
SCOTT@dev>SELECT FN_AGE_RANGE('01.11.2016') FROM DUAL;
FN_AGE_RANGE('01.11.2016')
>6 Months
SCOTT@dev>-- > 3 months
SCOTT@dev>SELECT FN_AGE_RANGE('01.02.2017') FROM DUAL;
FN_AGE_RANGE('01.02.2017')
3-6 Months
SCOTT@dev>SELECT FN_AGE_RANGE('01.07.2017') FROM DUAL;
FN_AGE_RANGE('01.07.2017')
Current
SCOTT@dev>--> NULL
SCOTT@dev>SELECT FN_AGE_RANGE(NULL) FROM DUAL;
FN_AGE_RANGE(NULL)