解决oracle数据库的表中存在异常日期值在查询时抛出ora-01841错误的办法

生产环境的服务器上,在查询时抛出SQLDataException,错误代码为ora-01841

ORA-01841: (完整) 年份值必须介于 -4713 和 +9999 之间, 且不为 0

经排查是在rs.next()语句中报错,导致后面的数据不能正常读取和显示,经多方判断,只能判断是表中的某个日期列被保存了一个异常日期值,在PLSQL中使用日期列排序时也会抛出此异常,表中的数据量也比较多,有十几万,无法精确的定位是哪一行数据的日期列有问题,网上也查不到相应的解决方案,后来无意中使用to_char函数查询年份

select distinct to_char(dt_column, 'yyyy') from tbl 

居然可以查询出结果,结果集中显示有数据的年份为0000,故基本上可以判断是存在年份为0的数据引起的异常,下面尝试使用以下SQL语句对数据进行校正

update em_t_equ$detail t set t.DT_REPLACE_DATE=null where to_char(t.DT_REPLACE_DATE,'yyyy')='0000' 
or to_number(to_char(t.DT_REPLACE_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_REPLACE_DATE,'yyyy'))<-1000;

执行后居然成功了,没有报错,为了保证将所有数据列的错误值都进行校正,可以使用SQL语句查出此表的所有日期类型的列名,然后结合excel,自动生成多个SQL语句

select * from user_tab_columns t where t.TABLE_NAME='EM_T_EQU$DETAIL' and data_type='DATE'

结果集:

EM_T_EQU$DETAIL    DT_REPLACE_DATE    DATE
EM_T_EQU$DETAIL    DT_NEXT$REPLACE$DATE    DATE
EM_T_EQU$DETAIL    DT_CS    DATE
EM_T_EQU$DETAIL    DT_USE_LIFE    DATE
EM_T_EQU$DETAIL    DT_LM_DATE    DATE
EM_T_EQU$DETAIL    DT_MIDDLE_DATE    DATE
EM_T_EQU$DETAIL    DT_BIG_DATE    DATE
EM_T_EQU$DETAIL    DT_NEXT$CHECK$DATE    DATE
EM_T_EQU$DETAIL    DT_NEXT$MIDDLE$DATE    DATE
EM_T_EQU$DETAIL    DT_NEXT$BIG$DATE    DATE
EM_T_EQU$DETAIL    DT_FACTORY_DATE    DATE
EM_T_EQU$DETAIL    DT_CHECK_DATE    DATE
EM_T_EQU$DETAIL    DT_EQU$USE$DATE    DATE
EM_T_EQU$DETAIL    DT_DATE    DATE

在PLSQL中可以单独复制第2列,粘贴到Excel中,在后面的单元格上填写公式:

="update em_t_equ$detail t set t."&I2&"=null where to_char(t."&I2&",'yyyy')='0000' or to_number(to_char(t."&I2&",'yyyy'))>9999 or to_number(to_char(t."&I2&",'yyyy'))<-1000;"

鼠标下拉复制,生成多个SQL语句,复制后在PLSQL中粘贴执行即可

update em_t_equ$detail t set t.DT_REPLACE_DATE=null where to_char(t.DT_REPLACE_DATE,'yyyy')='0000' or to_number(to_char(t.DT_REPLACE_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_REPLACE_DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_NEXT$REPLACE$DATE=null where to_char(t.DT_NEXT$REPLACE$DATE,'yyyy')='0000' or to_number(to_char(t.DT_NEXT$REPLACE$DATE,'yyyy'))>9999 or to_number(to_char(t.DT_NEXT$REPLACE$DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_CS=null where to_char(t.DT_CS,'yyyy')='0000' or to_number(to_char(t.DT_CS,'yyyy'))>9999 or to_number(to_char(t.DT_CS,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_USE_LIFE=null where to_char(t.DT_USE_LIFE,'yyyy')='0000' or to_number(to_char(t.DT_USE_LIFE,'yyyy'))>9999 or to_number(to_char(t.DT_USE_LIFE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_LM_DATE=null where to_char(t.DT_LM_DATE,'yyyy')='0000' or to_number(to_char(t.DT_LM_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_LM_DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_MIDDLE_DATE=null where to_char(t.DT_MIDDLE_DATE,'yyyy')='0000' or to_number(to_char(t.DT_MIDDLE_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_MIDDLE_DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_BIG_DATE=null where to_char(t.DT_BIG_DATE,'yyyy')='0000' or to_number(to_char(t.DT_BIG_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_BIG_DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_NEXT$CHECK$DATE=null where to_char(t.DT_NEXT$CHECK$DATE,'yyyy')='0000' or to_number(to_char(t.DT_NEXT$CHECK$DATE,'yyyy'))>9999 or to_number(to_char(t.DT_NEXT$CHECK$DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_NEXT$MIDDLE$DATE=null where to_char(t.DT_NEXT$MIDDLE$DATE,'yyyy')='0000' or to_number(to_char(t.DT_NEXT$MIDDLE$DATE,'yyyy'))>9999 or to_number(to_char(t.DT_NEXT$MIDDLE$DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_NEXT$BIG$DATE=null where to_char(t.DT_NEXT$BIG$DATE,'yyyy')='0000' or to_number(to_char(t.DT_NEXT$BIG$DATE,'yyyy'))>9999 or to_number(to_char(t.DT_NEXT$BIG$DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_FACTORY_DATE=null where to_char(t.DT_FACTORY_DATE,'yyyy')='0000' or to_number(to_char(t.DT_FACTORY_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_FACTORY_DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_CHECK_DATE=null where to_char(t.DT_CHECK_DATE,'yyyy')='0000' or to_number(to_char(t.DT_CHECK_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_CHECK_DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_EQU$USE$DATE=null where to_char(t.DT_EQU$USE$DATE,'yyyy')='0000' or to_number(to_char(t.DT_EQU$USE$DATE,'yyyy'))>9999 or to_number(to_char(t.DT_EQU$USE$DATE,'yyyy'))<-1000;
update em_t_equ$detail t set t.DT_DATE=null where to_char(t.DT_DATE,'yyyy')='0000' or to_number(to_char(t.DT_DATE,'yyyy'))>9999 or to_number(to_char(t.DT_DATE,'yyyy'))<-1000;

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 原因:Java程序在执行SQL语句发现表或视图不存在,导致抛出了java.sql.SQLSyntaxErrorException: ORA-00942异常。 可能的原因包括: 1. 数据库中确实不存在该表或视图; 2. 表或视图名称拼写错误; 3. 用户没有访问该表或视图的权限; 4. 数据库连接配置错误。 需要检查以上可能的原因,确保表或视图存在且名称拼写正确,用户有访问权限,并且数据库连接配置正确。 ### 回答2: 这是一个 Oracle 数据库系统的 SQL 语法错误,提示中指出了表或视图不存在。这意味着当前执行的 SQL 语句中引用了一个不存在的表或视图。 在 Oracle 数据库中,表和视图是很重要的数据库对象,它们存储了实际的数据和数据定义。如果 SQL 查询或操作要使用表或视图,首先我们必须确保这些表或视图确实存在并且已经被正确的创建、定义和加载数据。 当系统执行 SQL 语句,如果其中引用了一个不存在的表或视图,就会产生 "java.sql.sqlsyntaxerrorexception: ora-00942: 表或视图不存在" 这个错误。这种情况通常会发生在以下情况: 1. 拼写错误:在 SQL 中表名或视图名的拼写错误,例如大小写错误或少打了一个字母。 2. 对象名更改:在 SQL 中使用的表或视图名称已被更改或删除。 3. 没有权限:在 SQL 语句中引用的表或视图是另一个用户创建的对象,并且当前用户没有访问该对象的权限。 要解决此问题,我们需要检查 SQL 语句中是否存在拼写错误,确认表或视图是否存在并且是否拥有访问权限。如果这些都已经确认没有问题,那么可能是由于更深层次的数据库问题导致问题的产生,此需要进行更深入的故障排除。 ### 回答3: 本错误的产生是由于访问了一个不存在的表或视图。在Java应用程序中,该错误通常是由于SQL查询语句中的表或视图名称错误或被错误地输入所致。 “ORA-00942:表或视图不存在”是Oracle数据库的一个错误代码,指出用户试图查询一个不存在的表或视图。 在处理该错误,我们应该首先检查SQL语句是否正确,确认没有拼写错误或其他语法错误,并确保查询的表或视图确实存在数据库中。如果查询的表或视图不存在,我们需要创建该表或视图,并重新执行查询操作。 除了上述方法外,我们还可以通过查看数据库的日志来确定错误原因。在日志中,我们可以找到更多关于查询语句和错误代码的详细信息。 在编写Java应用程序,我们还可以使用调试工具来确定错误原因。通过打印SQL查询语句和数据库返回的错误代码,我们可以更快地诊断并解决问题。 总的来说,Java.sql.sqlsyntaxerrorexception: ora-00942是一种常见的错误,通常是由于应用程序中的错误SQL语句所导致的。我们可以通过检查语句的语法、确保所查询的表或视图存在、查看数据库日志以及使用调试工具来解决这一问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shuaijie506

您的打赏是我继续分享的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值