【问题标题】:error: The string representation of a date/time value is out of range错误:日期/时间值的字符串表示超出范围
【发布时间】:2019-09-19 20:43:49
【问题描述】:

我正在处理本地 java 数据库,但尝试在我的数据库表中插入日期时一直出现此错误

错误

错误代码 30000,SQL 状态 22007:日期/时间值的字符串表示形式超出范围

查询

INSERT INTO
   conference (titre, institut_organisatrice, date_conf, date_limite_soumission, date_limite_inscription, montant, frais_inscrit_pro, frais_inscrit_acadm, frais_inscrit_etud, idpresident) 
VALUES
   (
      'Smart Tunisia', 'ministere de la recherche scientifique', '05/10/2019', '20/09/2019', '20/09/2019', 300, 200, 150, 50, 1
   )
;

【问题讨论】:

  • 您应该标记您的 dbms 以获得更好的答案。如果您使用 ISO 日期,您可能会摆脱此错误:'20191005' 而不是 '05/10/2019'
  • SQL 日期的标准是yyyy-mm-dd。在任何情况下,如果您正在使用 JDBC,最好使用准备好的语句并将 setObjectLocalDate 或来自 java.time 的其他适用对象一起使用。
  • 然后它显示不正确的语法
  • '05/10/2019' 是 10 月 5 日还是 5 月 10 日?使用'YYYY-MM-DD' 的 ISO 标准要好得多,无论任何语言环境设置如何,它都可以在 DB2 中使用

标签: java sql database date db2


【解决方案1】:

tl;博士

myPreparedStatement                                   // Use a prepared statement for most of your SQL work, to pass objects in your JDBC code. Bonus: Doing so avoids SQL-injection attacks too.
.setObject(                                           // Replace a `?` placeholder in your SQL statement.
    … ,                                               // Specify which `?` placeholder.
    LocalDate.parse(                                  // Use `LocalDate` class for a date-only value without time-of-day and without time zone.
        "05/10/2019" , 
        DateTimeFormatter.ofPattern( "MM/dd/uuuu" )   // Specify a formatting pattern to match your input string.
    )
)

智能对象,而不是哑字符串

对于日期时间值,请在 SQL (DATE) 和 Java (LocalDate) 中使用日期时间类型。使用适当的类型而不是单纯的字符串使您的代码self-documenting,确保有效值,并提供type-safety

PreparedStatement & 占位符

更改您的 SQL 以使用 ? 占位符和 prepared statement。作为奖励,您将消除SQL-Injection 攻击的风险。

在 Stack Overflow 中搜索类名 PreparedStatement 以了解更多信息。这已经被报道过很多次了。

LocalDate

将您的字符串输入解析为LocalDate 对象。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ); 
LocalDate ld = LocalDate.parse( "05/10/2019" , f ) ;

为占位符指定值。

myPreparedStatement.setObject( … , ld ) ;

从数据库中的DATE 列检索时。

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

ISO 8601

提示:在将日期时间值序列化为文本时,学习使用标准的 ISO 8601 格式。仅使用本地化格式向用户展示,而不是在您的业务逻辑内部。

方便的是,java.time 类在生成和解析字符串时默认使用标准格式。

LocalDate.parse( "2019-05-10" )  // May 10, 2019. 

关于java.time

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

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

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    如果您的日期列是正确的日期数据类型
    你应该使用

    '2019/10/05'   
    

    str_to_date('05/10/2019', '%d/%m/%Y') 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多