相同的函数在Oracle中返回不同的结果

时间:2017-01-19 00:39:55

标签: oracle

我运行两个查询,他们返回不同的结果。请帮我找一下我错过的东西。

MyAnim

2 个答案:

答案 0 :(得分:2)

to_char(<date>, 'Month')生成一个长度等于任何月份名称的最大长度的字符串(在当前会话的语言中) - 它通过用空格填充来实现。这就是第二个查询没有产生结果的原因;如果你将upper....包裹在trim(...)中它会起作用,但最好不要使用to_char(..., 'Month')来开始这种查询。我相信你得出了同样的结论,但你只想知道发生了什么......

这是一个例子。看起来结果中的第一列似乎是字符串'March';但是,第二列不是谎言:第一列中的结果实际上是'March '(末尾有四个空格)。

select to_char(date '2016-03-01', 'Month')           as month_as_string,
       length( to_char(date '2016-03-01', 'Month') ) as len
from   dual
;

MONTH_AS_STRING  LEN
---------------  ---
March              9

然后你可能会问为什么Oracle做出了如此奇怪的选择。这是一个更棘手的问题。无论如何,记录了这种行为。 CPPCon 2016并向下滚动到表2.15中的MONTH

答案 1 :(得分:2)

正如mathguy所说,'MONTH'使用空格填充。试试

SELECT '"'||TO_CHAR(Hire_date, 'Month')||'"' FROM employees

看效果。使用函数TRIM或格式模型修饰符FM

然后TO_CHAR(Hire_date, 'Month')的结果取决于您当前的会话NLS_DATE_LANGUAGE值。其他会话可能会获得“März”或“Μάρτιος”。指定日期语言或使用月号。

实际上UPPER(TO_CHAR(Hire_date,'MONTH'))是多余的。格式MONTH以大写形式返回月份名称,您不必再次生成UPPER()

考虑到所有这些因素,您应该使用以下表达式之一

WHERE TO_CHAR(Hire_date, 'fmMONTH', 'NLS_DATE_LANGUAGE = english') = 'MARCH'

WHERE UPPER(TO_CHAR(Hire_date, 'fmMonth', 'NLS_DATE_LANGUAGE = english')) = 'MARCH'

WHERE TRIM(TO_CHAR(Hire_date, 'MONTH', 'NLS_DATE_LANGUAGE = english')) = 'MARCH'

WHERE TO_CHAR(Hire_date, 'MM') = '03'

WHERE EXTRACT(MONTH FROM Hire_date) = 3