我试图运行以下查询,但它似乎是错误
对于这些数据类型是varchar
查询
select *
from RP_REPORT_TEMP
where to_char(START_DATE,'FM DD YYYY HH24:MI:SS AM')
>= 'May 01 2016 00:00:00'
and to_char(END_DATE,'FM DD YYYY HH24:MI:SS PM')
<= 'May 31 2016 11:59:00'
and lower(rid) like '%a001%'
order by CAST(cid as INTEGER) asc
表格
|RID |START_DATE |END_DATE |
|--------------------|-------------------------- |-----------------------------|
|A001 |May 1 2016 12:00:00:000AM |May 31 2016 12:00:00:000PM |
|A001 |May 1 2016 12:00:00:000AM |May 31 2016 12:00:00:000PM |
|A001 |May 1 2016 12:00:00:000AM |May 31 2016 12:00:00:000PM |
虽然我试图执行此查询。查询返回一些错误。我该如何解决这个问题?
错误
SQL Error [1722] [42000]: ORA-01722: invalid number
java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
答案 0 :(得分:1)
为什么不在日期使用TO_DATE()
?
select * from RP_REPORT_TEMP
where START_DATE >= to_date('May 01 2016 12:00:00 AM','MON DD YYYY HH:MI:SS AM')
and END_DATE <= to_date('May 31 2016 11:59:00 AM','MON DD YYYY HH24:MI:SS AM')
and lower(rid) like '%a001%'
答案 1 :(得分:0)
试试这个..
select *
from RP_REPORT_TEMP
where TO_date(START_DATE,'MON DD YYYY HH:MI:SS AM')
>= to_Date('May 01 2016 12:00:00 AM' ,'MON DD YYYY HH:MI:SS AM')
and TO_DATE(END_DATE,'MON DD YYYY HH:MI:SS PM')
<= TO_DATE('May 31 2016 11:59:00 AM' ,'MON DD YYYY HH:MI:SS PM')
and lower(rid) like '%a001%'
order by CAST(cid as INTEGER) asc
select *
from RP_REPORT_TEMP
where TO_date(START_DATE,'MON DD YYYY HH24:MI:SS')
>= to_Date('May 01 2016 12:00:00' ,'MON DD YYYY HH24:MI:SS')
and TO_DATE(END_DATE,'MON DD YYYY HH24:MI:SS')
<= TO_DATE('May 31 2016 11:59:00' ,'MON DD YYYY HH24:MI:SS')
and lower(rid) like '%a001%'
order by CAST(cid as INTEGER) asc
答案 2 :(得分:0)
假设START_DATE
和END_DATE
实际上是日期,我可以在您的代码中发现两个主要问题:
将每一行转换为字符串的速度很慢,也会阻止Oracle使用索引(除非您有一个精心构建的基于函数的索引)。
词典排序(又名“A到Z”)不会在日期为“5月1日”的情况下呈现有意义的结果。想想这个列表有什么意义:Apr, Aug, Dec, Feb, Jan, Jul, Jun, Mar, May, Nov, Oct, Sep
我的建议是:
结果:
select *
from RP_REPORT_TEMP
where START_DATE
>= TO_DATE('2016-05-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and END_DATE
<= TO_DATE('2016-05-31 11:59:00', 'YYYY-MM-DD HH24:MI:SS')
and lower(rid) like '%a001%'
order by CAST(cid as INTEGER) asc
P.S。 START_DATE
和END_DATE
毕竟不是日期
答案 3 :(得分:0)
这是您的查询应该是这样的:
select *
from rp_report_temp
where to_date(start_date,'FM Mon DD YYYY HH:MI:SS"FMMon DD YYYY HH:MI:SS":000"AM', 'nls_date_language = english')
>= to_date('01/05/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')
and to_date(end_date,'FM Mon DD YYYY HH:MI:SS":000"AM', 'nls_date_language = english')
<= to_date('31/05/2016 23:59:59', 'dd/mm/yyyy hh24:mi:ss')
and lower(rid) like '%a001%'
order by cast(cid as integer) asc;
在这里,我已经将您的开始和结束日期列转换为日期,基于该列中的示例字符串看起来像&#34; 2016年5月1日12:00:00:000AM&#34; - 还有额外的&#34;:000&#34;几秒钟之后;我假设这总是&#34;:000&#34;。
注意我通过在to_date()
内专门设置该值,使我的代码nls_date_language参数独立。这意味着如果其他人的客户端设置为不是英语的东西,那么sql语句仍将适用于他们。
您注意到我并不需要为您正在测试的值执行此操作,因为我将字符串的格式更改为使用数字来表示月份的内容。
你也有一些基本的数据建模问题 - 通过将所有内容存储为varchar2
你已经为自己制作了一根杆 - 你已经失去了所有可用的验证(如果有人放了一个字符串会发生什么那列中的Feb 30 2015 39:99:99 AM
?AWOOGA,AWOOGA,错误!)。您已经使您的查询必须更加努力(现在我们已经在各处尝试将数据转换为正确的数据类型)。
您应该以正确的数据类型存储数据。日期应存储为DATE,时间戳记为TIMESTAMP,数字为NUMBER(有或没有特定的精度和比例)等。
如果您的数据存储正确,那么您的查询将是:
select *
from rp_report_temp
where start_date >= to_date('01/05/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')
and end_date <= to_date('31/05/2016 23:59:59', 'dd/mm/yyyy hh24:mi:ss')
and lower(rid) like '%a001%'
order by cid asc;