首页 > 解决方案 > ORA-01858: 在需要数字的地方发现了一个非数字字符

问题描述

我是 oracle 的初学者,需要有关以下查询的帮助:

select admin_id, to_date(date_created, 'DD-MM-YYYY'), name, mobile, email, (select status from status where status.status_id = admin.status_id) from admin;

这是我的表:

SQL> desc admin
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ADMIN_ID                  NOT NULL NUMBER(5)
 STATUS_ID                 NOT NULL NUMBER(5)
 DATE_CREATED                       TIMESTAMP(6)
 STATUS_DATE                        DATE
 NAME                           VARCHAR2(45)
 MOBILE                         VARCHAR2(20)
 EMAIL                          VARCHAR2(110)

SQL> desc status
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 STATUS_ID                 NOT NULL NUMBER(5)
 STATUS                         VARCHAR2(36)

主要问题是我想根据 admin.status_id 获取 status.status。日期可以通过将其用作 char 来固定to_char(date_created,'DD/MM/YYYY')

标签: jdbc

解决方案


to_date(date_created, 'DD-MM-YYYY')没有多大意义。

  • date_created是一个timestamp亚秒精度的 6 位十进制数字。
  • to_date接受一个字符串。因此 Oracle 必须首先使用会话的nls_timestamp_format. 那是被发送到的字符串to_date
  • to_date然后尝试使用“DD-MM-YYYY”格式掩码将该字符串转换回一个date(总是有一个时间分量)。除非这恰好是您nls_timestamp_format设置的内容,否则该转换将失败并且可能会抛出您报告的错误。

如果所有这些转换都有效,那么您最终会向 Java 应用程序发送一个将时间设置为午夜的日期。但是,作为一般规则,通常将时间戳发送回 Java 应用程序并让它处理如何将其转换为字符串以及需要显示时间戳的哪些组件会更有意义。所以我的默认设置是 select date_created

如果您确实希望 Oracle 进行数据类型转换并将时间组件设置date为午夜,则可以使用truncandcast代替。这避免了隐式数据类型转换并消除了对会话的nls_timestamp_format.

trunc( cast( date_created as date ) )

推荐阅读