我希望从给定日期开始一周中有6天,但是if子句没有采用'SUNDAY'。
V DATE :=TO_DATE (&H, 'DDMMYYYY');
V1 DATE:=V+6;
V2 VARCHAR(10);
BEGIN
WHILE V<V1 LOOP
V2:=TO_CHAR(V,'DAY');
IF V2='SUNDAY' THEN
DBMS_OUTPUT.PUT_LINE('TODAY IS SUNDAY');-- IF IS NOT TAKING THE VALUE
END IF;
DBMS_OUTPUT.PUT_LINE(V2||V);
V:=V+1;
END LOOP;
END;
输出:
FRIDAY 19-SEP-14
SATURDAY 20-SEP-14
SUNDAY 21-SEP-14
MONDAY 22-SEP-14
TUESDAY 23-SEP-14
WEDNESDAY24-SEP-14
答案 0 :(得分:2)
问题是TO_CHAR(V,'DAY')
在一天之后添加空格,因为它将当天填入最长的一天名称。您还可以在输出中看到这一点,其中所有日期完全对齐在彼此之下。
解决方案:Trim
值:
IF TRIM(V2) = 'SUNDAY' THEN
此问题也在此处描述:http://www.orafaq.com/forum/t/45942/0/
另一个不错的解决方案是使用numeric date language
作为NLS设置来获取日期编号:
V3 := TO_CHAR(V, 'DAY', 'NLS_DATE_LANGUAGE=''numeric date language''');
这样,TO_CHAR函数将从&#39; 1&#39;返回一个数字(作为字符串)。 (星期一)到&#39; 7&#39; (星期日),没有本地化,并且在周日可能是第一天时不受区域设置的影响。
numeric date language
是一种特殊的语言&#39;在哪一天的名字是数字。由于它实际上是一天的名称,因此您需要使用'DAY'
而不是'D'
,并且出于同样的原因,它不受该地区的影响。这是一个隐藏的功能,我认为它用于测试数据功能的本地化功能。优点是它不依赖于已安装的语言,但我想英语也将始终可用。
答案 1 :(得分:1)
作为TRIM()
的替代方法或使用带有DY
格式元素的缩写形式,您还可以使用the FM
fill-mode format modifier获取没有填充的完整日期名称:
V2:=TO_CHAR(V,'FMDAY');
IF V2='SUNDAY' THEN
...
当然,这会弄乱你的显示,因为你使用相同的V2
值,所以你会看到:
FRIDAY19-SEP-14
SATURDAY20-SEP-14
TODAY IS SUNDAY
SUNDAY21-SEP-14
MONDAY22-SEP-14
TUESDAY23-SEP-14
WEDNESDAY24-SEP-14
DAY
和DY
都受到您的NLS设置的影响,因此如果运行此操作的人碰巧在不同的区域设置中,则可能无法按预期工作;例如,对于法语国家的某个人,会看到DIMANCHE
不等于字符串文字'SUNDAY'
。您可以通过指定要使用的语言来删除可能的歧义:
V2:=TO_CHAR(V,'FMDAY','NLS_DATE_LANGUAGE=ENGLISH');
看起来有点矫枉过正,但如果你比较结果而不仅仅是显示结果,那就更安全了。既然你想要显示,你可以通过两次TO_CHAR()
来获得两者:
alter session set NLS_DATE_LANGUAGE=SPANISH;
DECLARE
V DATE :=TO_DATE (&H, 'DDMMYYYY');
V1 DATE:=V+6;
BEGIN
WHILE V<V1 LOOP
IF TO_CHAR(V,'FMDAY','NLS_DATE_LANGUAGE=ENGLISH')='SUNDAY' THEN
DBMS_OUTPUT.PUT_LINE('TODAY IS SUNDAY');
END IF;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(V,'DAY')||V);
V:=V+1;
END LOOP;
END;
/
VIERNES 19-SEP-14
SÁBADO 20-SEP-14
TODAY IS SUNDAY
DOMINGO 21-SEP-14
LUNES 22-SEP-14
MARTES 23-SEP-14
MIÉRCOLES24-SEP-14
比较始终采用固定语言,但显示将采用会话语言。
除了轻松显示星期日日期和“今天星期天”消息外,您还可以在纯SQL中执行此操作;或者使用更简单的PL / SQL循环。取决于你现实世界的用途。