我有一个表,每个客户(主表)都有一个记录。然后,我为一些客户提供了一张表格,其中包含更多细附加详细信息表有时没有主表中记录的记录。有时,详细信息表在主表和记录表中有多条记录。如果是这种情况,我需要最近的记录(因此最大子选择)。
问题是我的函数只返回详细信息表中少数记录的值。如果我注释掉查看详细信息表的函数部分并返回STAT3
值,它似乎工作。如果该查询有结果,我如何才能使下面的第二个选择规则适用?
create or replace FUNCTION "F_RETURN_STAT" (
N_UNIQUE IN NUMBER)
RETURN VARCHAR2
IS
V_STAT3 varchar2(20);
V_STAT varchar2(20);
V_STAT2 varchar2(20);
D_ACTDATE date;
D_STARTDATE date;
BEGIN
select expire into D_ACTDATE
from main_table a
where a.uniquefield = N_UNIQUE;
IF
D_ACTDATE > SYSDATE
or
D_ACTDATE is null
then
V_STAT :='TRUE';
else
v_STAT :='FALSE';
end if;
select b.startdate into D_STARTDATE
from main_table a, detail_table b
where a.uniquefield= b.main_table_id(+) and
b.main_table_id = N_UNIQUE and
b.uniquefield in
(select max(c.uniquefield) from detail_table c group by main_table_id);
if
D_STARTDATE is not null
then
V_STAT2 :='FALSE';
end if;
if
V_STAT2 ='FALSE'
then
V_STAT3 :='FALSE';
ELSE
V_STAT3 := V_STAT;
end if ;
RETURN(V_STAT3);
end;
答案 0 :(得分:1)
我认为此版本的功能可以解决您的问题:
CREATE OR REPLACE FUNCTION f_return_stat(n_unique IN NUMBER)
RETURN VARCHAR2 IS
v_stat3 VARCHAR2(20);
v_stat VARCHAR2(20);
v_stat2 VARCHAR2(20);
d_actdate DATE;
d_startdate DATE;
BEGIN
--First Query
SELECT expire
INTO d_actdate
FROM main_table a
WHERE a.uniquefield = n_unique;
IF d_actdate > SYSDATE OR d_actdate IS NULL THEN
v_stat := 'TRUE';
ELSE
v_stat := 'FALSE';
END IF;
BEGIN
--Second Query
SELECT b.startdate
INTO d_startdate
FROM detail_table b
WHERE b.main_table_id = n_unique
AND b.uniquefield IN (SELECT MAX(c.uniquefield)
FROM detail_table c
GROUP BY main_table_id);
EXCEPTION
WHEN NO_DATA_FOUND THEN
d_startdate := NULL;
END;
IF d_startdate IS NOT NULL THEN
v_stat2 := 'FALSE';
END IF;
IF v_stat2 = 'FALSE' THEN
v_stat3 := 'FALSE';
ELSE
v_stat3 := v_stat;
END IF;
RETURN (v_stat3);
END;
在第二个查询的版本中,您的加入(a.uniquefield= b.main_table_id
)和过滤器(b.main_table_id = N_UNIQUE
)是等效的,因此可以完全删除main_table a
。保留它的唯一原因是确保您的查询始终返回一行。如果您使用异常处理来捕获NO_DATA_FOUND
异常,那么这种需求就会消失,您可以简化查询,只需从detail_table b
中选择。
答案 1 :(得分:0)
我相信可能有一种更有效的方式,但这可能会起到作用:
SELECT b.startdate
INTO d_startdate
FROM detail_table b
WHERE b.main_table_id = n_unique
and
(b.uniquefield in
(select max(c.uniquefield) from detail_table c group by main_table_id)
or b.uniquefield is null);