代码:
CREATE OR REPLACE FUNCTION DAY_ORD_SF
(
P_DATE_CREATED IN bb_basket.dtcreated%type
)
RETURN DATE AS
lv_date_created bb_basket.dtcreated%type;
BEGIN
SELECT to_char(to_date(P_DATE_CREATED,'yyyy-mm-dd'),'DAY') DAY_CREATED
INTO lv_date_created
FROM BB_BASKET
WHERE lv_date_created <= sysdate
ORDER BY lv_date_created ASC;
RETURN lv_date_created;
END DAY_ORD_SF;
/
SELECT IDBASKET, dtcreated date_created, to_char(DTCREATED,'DAY') DAY_CREATED, day_ord_sf(dtcreated) weekday_created
FROM BB_BASKET
order by DTCREATED asc;
这是我作为练习存储功能的任务而正在处理的功能。我真的快要完成此问题了,但是却遇到了找不到数据的错误。我不是真的理解此错误,因为当我自己运行代码时,它可以工作。基本上,该函数假定获取日期并返回varchar2数据类型。在将那段代码添加到函数中之前,我确实没有“ to_date(...,'yyyy-mm-dd'),..”。 此任务的第一部分是创建一个SELECT语句,该语句列出每个购物篮的购物篮ID和工作日,第二部分是创建SELECT语句,使用GROUP BY子句列出每个工作日的购物篮总数。根据结果,什么是最受欢迎的购物日?我也忘了问,如果您能告诉我为什么我收到“找不到数据”错误,将不胜感激!
感谢您的帮助!
答案 0 :(得分:0)
好吧,这里似乎有多个问题。
让我们开始没有发现数据问题。如果在select语句中使用INTO且select不返回任何行,则会出现未找到数据的异常。这可以通过内部带有异常处理程序的anonyme begin end块来处理,但我认为并非如此。例如:
declare
v_value number;
begin
select null
into v_value
from dual
where 1=2;
exception
when NO_DATA_FOUND then
null; -- Ignore exception and continue
end;
永远不会满足条件1 = 2,因此选择始终不返回任何行,这将始终不会产生未找到数据的错误。使用异常处理程序,我们可以决定下一步要做什么。在此示例中,Null无效。
返回到函数,您的条件是,如果变量lv_date_created小于或等于当前日期,则执行某项操作。这将永远无法工作,因为lv_date_created在执行时等于null。它只是在您的函数中声明,然后在您的选择中使用。这将始终导致false,因此select将始终不返回任何行,也不会找到任何数据。
您还提到要让函数返回varchar2,但定义说它返回日期。同样,变量lv_date_created的类型为date,并且返回该变量,并用varchar2值填充该变量,因此显然Oracle正在对该值进行一些不受控制的转换,不会引发预期数据类型的异常。
条件lv_date_created <= sysdate也可能表明select将找到多个值,如果使用INTO,如果找到多个行,这将导致太多的行异常。
现在让我们来修复此功能。主要问题是您是否需要选择其中的某些内容。通常选择类似的选项来检查表中的条目是否存在,并且没有发现数据异常会告诉我们该条目不存在。如果它是用于数据库中多个位置的通用功能,那么我认为不需要select。我将以这两种解决方案为例。
请注意,对于第一个,您不应再提供dtcreated的colume而是idbasket。
CREATE OR REPLACE FUNCTION DAY_ORD_SF
(
P_IDBASKET IN bb_basket.idbasket%type
)
RETURN VARCHAR2 AS
lv_date_created VARCHAR2(240);
BEGIN
SELECT to_char(dtcreated,'DAY') DAY_CREATED
INTO lv_date_created
FROM BB_BASKET
WHERE IDBASKET = P_IDBASKET;
RETURN lv_date_created;
END DAY_ORD_SF;
/
或
CREATE OR REPLACE FUNCTION DAY_ORD_SF
(
P_DATE_CREATED IN bb_basket.dtcreated%type
)
RETURN VARCHAR2 AS
BEGIN
RETURN to_char(P_DATE_CREATED,'DAY');
END DAY_ORD_SF;
/