繁体   English   中英

如何在 Java 中插入 Oracle 日期数据类型

[英]How To Insert Oracle Date Data type in Java

大家好

我是 java 的新手。 我试图创建这样一个数据 pipe 行,将表从 1 个源复制到不同的服务器和数据库。 它适用于字符串和数字,但我停留在日期数据类型。 在线程“main”中遇到异常 java.sql.SQLException: ORA-01843: not a valid month

我不知道如何更改 java 中的日期格式或使用日期数据类型。

这里是详细信息:Oracle 10g (Svr1) & 11g (Svr2), java 8 with ojdbc14.Z68995FCBF432492D15484DAC04ZA

表的数据库

Table = LAB
field = ID(INT), LAB_DESC(VARCHAR2, 50), LAB_DATE(DATE)

Java 代码

//========= Bismillah Arrahman Arrahiem =============//
//============== DARI SINI ========================================//
//    **    **  **  **
//  ****    **  **  **     ****        ** ** **     ** 
//  ****    **  **  **     *  *        ** ** **     **
//     **********   **   ****************************
//                                             *
//
//========================= LAB =============================//
package simpledtpipeline;
import java.sql.*;
public class SimpleDTpipeline {

     public static void main(String[] args) 
       //========= Bismillah =============//
        throws SQLException, ClassNotFoundException, Exception {
 // Load the JDBC driver
 Class.forName("oracle.jdbc.driver.OracleDriver");
 System.out.println("Driver loaded");
//======================================================// 
 // Connect to a database
Connection connectionServer1 = DriverManager.getConnection
("jdbc:oracle:thin:@192.168.7.1:1521:dbone", "user", "pass123");
 System.out.println("Database 192.168.7.1 connected");
//======================================================//
Connection connectionServer2 = DriverManager.getConnection
("jdbc:oracle:thin:@192.168.7.2:1521:dbtwo", "user2", "pass789");
System.out.println("Database 192.168.7.2 connected");
//
//========================= LAB =============================//
Statement SelectLAB = connectionServer1.createStatement();
// Execute a statement
 ResultSet FetchLAB = SelectLAB.executeQuery
("SELECT ID, LAB_DESC, LAB_DATE from LAB ");
//*****************************************************************//
PreparedStatement InsertLAB = connectionServer2.prepareStatement("INSERT INTO LAB "
        + "(ID, LAB_DESC, LAB_DATE) VALUES (?,?, TO_DATE(?,'MM/DD/YYYY')");
while (FetchLAB.next()){
    InsertLAB.setInt(1,FetchLAB.getInt("ID")); 
    InsertLAB.setString(2,FetchLAB.getString("LAB_DESC")); 
    InsertLAB.setString(3,FetchLAB.getString("LAB_DATE")); 
    InsertLAB.execute(); 
}
//======================================================//
//
// Close the connection //
 connectionServer1.close();
 connectionServer2.close();
}
       
    }

tl;博士

myPreparedStatement
.setObject(                                           // Use `setObject` for java.time types.
    3 ,                                               // Third placeholder in the Question's example text.
    LocalDate                                         // Represent a date-only value, without time-of-day and without time zone.
    .parse(
        "01/23/2020" , 
        DateTimeFormatter.ofPattern( "MM/dd/uuuu" )   // Specify formatting codes for your particular text input’s format. Case-sensitive.
    )
)

格式化代码

我猜你的代码中的具体问题是不正确的格式代码: 'MM/DD/YYYY' 我不知道 Oracle 数据库代码,但我猜它们是区分大小写的,正如在其他此类工具中看到的那样。 如果是这样,您可能使用了错误的案例。 或者您的格式代码与输入的实际文本不匹配。

无论哪种方式,这个问题都没有实际意义。 您应该为您的日期时间值而不是纯文本传递 Java 对象。

在 Java 中使用日期时间对象

您在 Java 方面的日期时间对象,而不仅仅是字符串。

仅使用 Java 中的java.time类,切勿使用DateCalendarSimpleDateFormat等遗留类。

JDBC 4.2需要JDBC 驱动程序来支持java.time类型的子集。

Java(传统和现代)和标准 SQL 中的日期时间类型表

但不幸和神秘的是,该规范没有java.time类型提供特定类型的set…方法。 相反,我们在准备好的语句上使用setObject ,在结果集上使用getObject

LocalDate localDate = LocalDate.of( 2022 , Month.JANUARY , 23 ) ;
myPreparedStatement.setObject( … , localDate ) ;

和检索。

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;

如果您的输入是月/日/年数字格式的文本,请解析为LocalDate对象。 在输入错误的情况下捕获DateTimeParseException

String input = "01/23/2022" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate localDate = LocalDate.parse( input , format ) ;

在数据交换中对此类文本使用本地化格式是一种不好的做法。 我建议您向该文本数据的发布者介绍有关日期的ISO 8601标准格式:YYYY-MM-DD。 所以 2022 年 1 月 23 日是2022-01-23

不相关的提示

调用Class.forName来加载 JDBC 驱动程序是老式的。 现代 Java 不再需要。

通常建议为您的特定数据库使用DataSource实现,而不是保存信息以建立数据库连接。 您的 JDBC 驱动程序应该提供这样的实现。

JDBC 资源如ConnectionResultSet实现了AutoCloseable接口。 这意味着我们可以使用try-with-resources语法来自动关闭这些资源,同时简化我们的代码。


关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代了麻烦的日期时间类,例如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle 教程 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序 不需要字符串,不需要java.sql.*类。 Hibernate 5 & JPA 2.2 支持java.time

从哪里获得 java.time 课程?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM