sql - 将 PL/SQL 中订单日期的工作日标识为存储函数
问题描述
代码:
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 子句列出每个工作日的篮子总数. 根据结果,最受欢迎的购物日是哪一天?另外我忘了问,如果你能告诉我为什么我得到“
谢谢你的协助!
解决方案
好吧,这里似乎有多个问题。
让我们从没有发现数据的问题开始。如果您在 select 语句中使用 INTO 并且 select 不返回任何行,您会得到一个 no data found 异常。这可以通过带有异常处理程序的匿名开始结束块来处理,但我相信情况并非如此。例如:
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。它只是在您的函数中声明,然后在您的选择中使用。这将始终导致错误,因此 select 将始终不返回任何行且未找到数据异常。
您还提到您希望函数返回 varchar2 但您的定义说它返回日期。变量 lv_date_created 也是 date 类型,这是返回的变量,你用 varchar2 值填充它,所以显然 Oracle 正在对 this 的值进行一些不受控制的转换,不会引发有关预期数据类型的异常。
此外,条件 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;
/
推荐阅读
- css - Internet Explorer 11 中的 Div 大小不起作用
- reactjs - 由于调用 axios,无法用玩笑测试 React 组件
- android - 某些 Android 设备的浏览器中的字体大小不规则
- r - 带有原生 R 对象的 SQL 语句
- kotlin - 从 Dart 向 Kotlin 发送回调函数
- python - 如何在 macOS 中使用下载的 Python 包?
- java - Jasper 报告 - 数字格式问题
- javascript - 如果有多个 AND、OR、NOT,则将句子拆分为引用的短语
- python - 如何通过发送与模型相关的 objects.all() 来获取外键
- python - 你能解释一下这个答案是正确的吗?