如何在Oracle SQL
中编写代码(例如将'CCYYMMDD'
写入102
)?
如果有人将在前端输入日期,则该值应返回102
而不是日期。
为此,如何在Oracle PLSQL
中编写函数。
https://www.unece.org/trade/untdid/d00a/tred/tred2379.htm 这些是ANSI标准格式。
答案 0 :(得分:2)
您无法编写函数来确定哪个数字日期字符串与哪种格式相对应,因为日期字符串可以是多种格式:
例如,010203
可以是:
DDMMYY
03年2月1日MMDDYY
03年1月2日YYMMDD
01年2月3日DDHHMM
02:03 HHMMSS
01:02:03 MMMMSS
102分3秒CCYYMM
,0102年3月CCYYWW
0102的第3周类似10080102
可能是:
DDMMCCYY
,102年8月10日CCYYMMDD
1008年1月2日MMDDHHMM
10月8日01:02 HHMMHHMM
时间跨度从10:08到01:01 如果有人以“ CCYYMMDD”格式插入日期,则该值应仅在前端返回默认值102。如何用SQL编写代码?
您不能像我上面描述的那样含糊不清某些值是什么,它们可能返回多种格式。相反,您应该在用户输入日期时创建另一列并存储日期格式,而不要尝试从(模糊的)数字中重建格式代码。
答案 1 :(得分:0)
如果要将Oracle日期转换为儒略日期,则可以使用以'j'为格式的TO_CHAR函数。
SELECT TO_CHAR(TO_DATE('BC47120412', 'BCYYYYMMDD'), 'J')
FROM DUAL;
Output: 0000102
如果要将朱利安日期转换为Oracle日期,请在下面使用查询,
SELECT TO_DATE(102, 'J')
FROM DUAL;
Output: 04/12/4712 12:00:00 AM BC
答案 2 :(得分:0)
您可以验证字符串是否适合这样的日期格式:
create or replace function is_CCYYMMDD
(p_str in varchar2)
return boolean
is
rv boolean;
dt date;
begin
begin
dt := to_date(p_str, 'YYYYMMDD');
dt := to_date('2000' || substr(p_str, 5), 'YYYYMMDD');
rv := true;
exception
when others then
rv := false;
end;
return rv;
end;
第一个to_date()
仅检查整个字符串是否为有效日期。第二个to_date()
检查字符串的后半部分是否是有效的月份和日期组合。这部分解决了@MTO observations的问题,即当某些字符串可以容纳多种格式时,强制执行严格的格式。
请注意,尽管存在歧义,例如,有可能通过该测试的有效日期是完全可能的。是20111012
或'YYYYMMDD'
中的'DDMMYYYY'
?除非您通过使用日期选择器小部件或年,月,日的单独输入框在前端输入中实施严格的日期格式,否则无法确定。
为什么在此查询中传递“ 2000”?
第二个检查将验证最后四个字符在月和日是否有效。每当我们进行这种测试时,我们都会遇到leap年的问题。如果我们仅应用to_date(str, 'MMDD')
,Oracle将默认年份为当年:2018029
的原始输入有效的时间是20160229
的错误日期。我的函数通过将year元素固定为2000年来避免这种情况,这是a年。
顺便说一句,如果要在SQL中使用此函数,则需要将返回数据类型更改为varchar2(Y / N标志)或数字(1/0),因为SQL不支持Booolean。