标签:
d9判断时分秒非法字符可移植性 |
分类: ORACLE |
判断字符型日期是否是合法的日期格式
ORA-01847 ORA-01843
日月明王的BLOG http://blog.sina.com.cn/u/1727546625
-
SQL1
select to_date(SALEDATE,'YYYYMMDD') from TM_WWM
b
ERROR at line 1:
ORA-01847: day of month must be between 1 and last day of
month
-
SQL2
select count(*) from TM_WWM
and substr(saledate,1,4) between 1970 and 2008
and substr(saledate,5,2) between '01' and '12'
and SALEDATE
AND
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD')
AND
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD')
ERROR at line 7:
ORA-01843: not a valid month
是取得本日期所在月的第一天,比如SALEDATE是20070312,则这里得到是20070301;
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD')是得到本日期下月第一天,是20070401,那么在这两个日期之间的就应该是合法日期了。
-
SQL3
select
distinct(to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD'))
from TM_WWM
and substr(saledate,1,4) between 1970 and 2008
and substr(saledate,5,2) between '01' and '12'
-
SQL4
select count(*) from
(select * from TM_WWM
and substr(saledate,1,4) between 1970 and 2008
and substr(saledate,5,2) between '01' and '12')
where SALEDATE
AND
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD')
1981098 行记录
注意SQL2和SQL4的区别,SQL2 是年月日的限制都在同一级,那么SQL是按照从右到左去分析执行(以前一直认为不是所有的RBO都是从右到左,所以一直都不在意,今天吃到苦头了,你也可以把先后顺序颠倒下,效果和SQL4一样),SQL4则年月在内侧,在符合年月的情况下“日期“都在本月1号到下月1号之间。到这里就能说SELECT的字符型日期都满足日期格式吗?
-
SQL4
select count(to_date(SALEDATE,'YYYYMMDD')) from (select * from
(select * from TM_WWM
and substr(saledate,1,4) between 1970 and 2008
and substr(saledate,5,2) between '01' and '12')
where SALEDATE
AND
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD'))
却不行
ERROR at line 1:
ORA-01839: date not valid for month specified
AND
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1),'YYYYMMDD'))的范围是20060201和20060301,而字符型20060230也在这个范围内,所以也符合条件能被选出,而to_date(SALEDATE,'YYYYMMDD')的时候却非法了。当时之所以考虑用20060201和20060301范围是因为考虑到时分秒的情况,而本例却没有时分秒,所以将范围改为
-
SQL5
select * from (select * from TM_WWM
and substr(saledate,1,4) between 1970 and 2008
and substr(saledate,5,2) between '01' and '12'
)
where SALEDATE
AND
to_char(ADD_MONTHS(to_date(SUBSTR(SALEDATE,1,6),'YYYYMM'),1)-1,'YYYYMMDD')