使用 CAST 时格式化日期

Formatting date when using CAST

我想使用 CASTDATE 类型转换为 VARCHAR2 类型。

DBUSER >SELECT CAST(CURRENT_DATE AS VARCHAR2(20)) THE_DATE from DUAL;
THE_DATE
--------------------
09-AUG-17

但是,我需要将 VARCHAR2 结果格式化为 'YYYYMM'。我知道我可以通过更改会话日期格式来实现此效果,但我宁愿不这样做。

DBUSER >ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMM';
Session altered.

DBUSER >SELECT CAST(CURRENT_DATE AS VARCHAR2(20)) THE_DATE from DUAL;
THE_DATE
--------------------
201708

我想避免使用 Oracle 专有的 TO_CHAR() 函数。有人对如何做到这一点有建议吗?

这可能对你有帮助:

SELECT extract(year from CURRENT_DATE) || case when extract(month from CURRENT_DATE) <10 THEN '0' || extract(month from CURRENT_DATE) END  THE_DATE from DUAL;

I am trying to standardize on ANSI SQL to the degree possible and avoid proprietary vendor nonstandard implementations.

ANSI SQL92 standard 中没有指定将 DATETIME 数据类型格式化为字符串的函数。

最简单的解决方案是使用 Oracle 为此目的提供的功能:

SELECT TO_CHAR( yourdate, 'YYYYMM' ) FROM yourtable;

但是,您可以使用 EXTRACT 函数(符合 ANSI 标准)获取年份和月份的组成部分:

SELECT EXTRACT( YEAR FROM yourdate ),
       EXTRACT( MONTH FROM yourdate )
FROM   yourtable;

然后您需要将数字转换为字符串并连接字符串:

SELECT TO_CHAR( EXTRACT( YEAR FROM yourdate ) )
       || TO_CHAR( EXTRACT( MONTH FROM yourdate ) )
FROM   yourtable

但你试图避免 TO_CHAR 所以你可以这样做:

SELECT CAST( EXTRACT( YEAR FROM yourdate ) AS VARCHAR2(4) )
       || CAST( EXTRACT( MONTH FROM yourdate ) AS VARCHAR2(2) )
FROM   yourtable

或者,使用隐式转换

SELECT EXTRACT( YEAR FROM yourdate )
       || EXTRACT( MONTH FROM yourdate )
FROM   yourtable

但是,如果年份不是4位数字或者月份不是2位数字,那么您需要填充这些值;同样,简单的解决方案是 TO_CHAR:

SELECT TO_CHAR( EXTRACT( YEAR FROM yourdate ), 'FM0000' )
       || TO_CHAR( EXTRACT( MONTH FROM yourdate ), 'FM00' )
FROM   yourtable

LPAD:

SELECT LPAD( EXTRACT( YEAR FROM yourdate ), 4, '0' )
       || LPAD( EXTRACT( MONTH FROM yourdate ), 4, '0' )
FROM   yourtable

但这些都不在 ANSI 标准中,所以:

SELECT CASE
         WHEN EXTRACT( YEAR FROM yourdate ) < 10 THEN '000'
         WHEN EXTRACT( YEAR FROM yourdate ) < 100 THEN '00'
         WHEN EXTRACT( YEAR FROM yourdate ) < 1000 THEN '0'
         ELSE NULL
       END
       || EXTRACT( YEAR FROM yourdate )
       || CASE
         WHEN EXTRACT( MONTH FROM yourdate ) < 10 THEN '0'
       END
       || EXTRACT( MONTH FROM yourdate )
FROM   yourtable;

而且我们已经成功地将单个 Oracle 函数转换为 ANSI 兼容表达式的庞然大物。

但是,Oracle 的 DATE 数据类型不符合 ANSI 标准(它是 ANSI DATETIME 数据类型的串联)所以我会问它是否是值得 - 特别是如果您随后考虑显示日期的时间部分(除非您首先使用 CASTDATE 转换为 TIMESTAMP,否则 EXTRACT 不会提取) .

SELECT TO_CHAR( yourdate, 'YYYYMMDDHH24MISS' ) FROM yourtable

SELECT CASE
         WHEN EXTRACT( YEAR FROM yourdate ) < 10 THEN '000'
         WHEN EXTRACT( YEAR FROM yourdate ) < 100 THEN '00'
         WHEN EXTRACT( YEAR FROM yourdate ) < 1000 THEN '0'
         ELSE NULL
       END
       || EXTRACT( YEAR FROM yourdate )
       || CASE
         WHEN EXTRACT( MONTH FROM yourdate ) < 10 THEN '0'
       END
       || EXTRACT( MONTH FROM yourdate )
       || CASE
         WHEN EXTRACT( DAY FROM yourdate ) < 10 THEN '0'
       END
       || EXTRACT( DAY FROM yourdate )
       || CASE
         WHEN EXTRACT( HOUR FROM CAST( yourdate AS TIMESTAMP ) ) < 10 THEN '0'
       END
       || EXTRACT( HOUR FROM CAST( yourdate AS TIMESTAMP ) )
       || CASE
         WHEN EXTRACT( MINUTE FROM CAST( yourdate AS TIMESTAMP ) ) < 10 THEN '0'
       END
       || EXTRACT( MINUTE FROM CAST( yourdate AS TIMESTAMP ) )
       || CASE
         WHEN EXTRACT( SECOND FROM CAST( yourdate AS TIMESTAMP ) ) < 10 THEN '0'
       END
       || EXTRACT( SECOND FROM CAST( yourdate AS TIMESTAMP ) )
FROM   yourtable;

[TL/DR] 只需使用 TO_CHAR