繁体   English   中英

Oracle Case语句不起作用

[英]Oracle Case statement not working

我正在尝试使用以下case语句从我的表中提取信息,如果我忽略case语句并手动输入它的工作日,但case语句不是它似乎只是直接跳转到else部分,任何建议好吗?

SELECT * FROM mytable WHERE day = CASE WHEN to_char(SYSDATE, 'DAY') = 'SATURDAY' THEN 'Sat'
                                       WHEN to_char(SYSDATE, 'DAY') = 'SUNDAY' THEN 'Sun'
                                       ELSE 'weekday' END;

由于某种原因,to_char函数使用末尾的空格填充字符串,但它不匹配。 我试过这个:

select '#' || to_char(SYSDATE+2, 'DAY') || '#' from dual 

它返回了: #SUNDAY #

将您的查询更改为:

SELECT * FROM mytable WHERE day = CASE WHEN trim(to_char(SYSDATE, 'DAY')) = 'SATURDAY' THEN 'Sat'
                                       WHEN trim(to_char(SYSDATE, 'DAY')) = 'SUNDAY' THEN 'Sun'
                                       ELSE 'weekday' END;

如果您查看文档,它会指出“DAY” - 日期名称,填充空白以显示此元素使用的日期语言中最宽的日期名称的宽度。

不是我的预期。

有两点需要注意:

  1. 无需手动TRIM空白填充。 Oracle提供FM即填充模式格式以消除空白填充。

  2. 您应该明确提及NLS_DATE_LANGUAGE因为格式取决于NLS

从关于格式模型修饰符的 Oracle文档:

调频

填充模式。 Oracle使用尾随空白字符和前导零来将格式元素填充到恒定宽度。 宽度等于相关格式模型的最大元素的显示宽度:

  • 数字元素用前导零填充到元素允许的最大值的宽度。 例如,YYYY元素填充为四位数(长度为“9999”),HH24填充为两位数(长度为“23”),DDD填充为三位数(长度为“366”)。

  • 字符元素MONTH,MON,DAY和DY用尾随空格填充到有效名称中最长的完整月份名称,最长的缩写月份名称,最长的完整日期名称或最长的缩写日期名称的宽度由NLS_DATE_LANGUAGE和NLS_CALENDAR参数的值确定。 例如,当NLS_DATE_LANGUAGE为AMERICAN且NLS_CALENDAR为GREGORIAN(默认值)时,MONTH的最大元素为SEPTEMBER,因此MONTH格式元素的所有值都填充为九个显示字符。 NLS_DATE_LANGUAGE和NLS_CALENDAR参数的值在TO_CHAR和TO_ * datetime函数的第三个参数中指定,或者从当前会话的NLS环境中检索它们。

  • 字符元素RM用尾随空格填充长度为4,即'viii'的长度。

  • 其他字符元素和拼写的数字(SP,SPTH和THSP后缀)未填充。

FM修饰符在TO_CHAR函数的返回值中抑制上述填充。

因此,您可以使用FMDAY而不是DAY格式来摆脱空白填充

例如,

SQL> SELECT '#' || to_char(SYSDATE, 'fmDAY') || '#' as dt FROM dual;

DT
-----------
#SATURDAY#

SQL>

因此,您可以将案例陈述修改为:

SQL> SELECT
  2    CASE
  3      WHEN TO_CHAR(SYSDATE, 'FMDAY') = 'SATURDAY'
  4      THEN 'Sat'
  5      WHEN TO_CHAR(SYSDATE, 'FMDAY') = 'SUNDAY'
  6      THEN 'Sun'
  7      ELSE 'weekday'
  8    END as day
  9  FROM dual;

DAY
-------
Sat

SQL>

使用NLS_DATE_LANGUAGE

例如,

SQL> ALTER SESSION SET NLS_DATE_LANGUAGE='french';

Session altered.

SQL>
SQL> SELECT '#' || to_char(SYSDATE, 'fmDAY') || '#' as dt FROM dual;

DT
----------
#SAMEDI#

SQL>
SQL> ALTER SESSION SET NLS_DATE_LANGUAGE='english';

Session altered.

SQL>
SQL> SELECT '#' || to_char(SYSDATE, 'fmDAY') || '#' as dt FROM dual;

DT
-----------
#SATURDAY#

SQL>

因此,您需要在个别声明级别提及它:

SQL> SELECT
  2    CASE
  3      WHEN TO_CHAR(SYSDATE, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH') = 'SATURDAY'
  4      THEN 'Sat'
  5      WHEN TO_CHAR(SYSDATE, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH') = 'SUNDAY'
  6      THEN 'Sun'
  7      ELSE 'weekday'
  8    END AS DAY
  9  FROM dual;

DAY
-------
Sat

SQL>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM