「0000-00-00 00:00:00」はjava.sql.Timestampエラーとして表すことができません


141

日付を含むデータベーステーブルがあります

 (`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'). 

MySQLを使用しています。プログラムから、データが日付なしでデータベースに渡されることがあります。したがって、日付の値は0000-00-00 00:00:00 、テーブルデータがエラーを発生する日付列で呼び出されたときに自動的に割り当てられます

...'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp.......

データを挿入するときに日付にnull値を渡そうとしましたが、現在の時刻に割り当てられます。

ResultSetテーブル構造を変更せずにを取得する方法はありますか?

回答:


302

このJDBC URLをデータソース構成で直接使用できます。

jdbc:mysql:// yourserver:3306 / yourdatabase?zeroDateTimeBehavior = convertToNull


2
奇妙な。他の答えを読んでください、まあ、ゼロ月はありません。これはどういう意味ですか?
Thufir 2014

2
jdbc URLに追加するMariaDBの同等物があるかどうか知っていますか?jdbc:mariadb:// localhost:3306 / dev?zeroDateTimeBehavior = convertToNullが機能しないようです。
jeffkempf 2017年

私にとってCONVERT_TO_NULLでなければなりませんでした
routeburn

16

「日付」「0000-00-00」が有効な「日付」であるかどうかは、質問とは無関係です。「データベースを変更するだけ」が実行可能な解決策になることはほとんどありません。

事実:

  • MySQLでは、値がゼロの日付を使用できます。
  • この「機能」は、他の言語で広く使用されています。

したがって、「データベースを変更するだけ」の場合、何千行ものPHPコードが壊れます。

Javaプログラマは、MySQLゼロ日付を受け入れるために必要彼らは他の言語は、この「機能」に依存しているとき、データベースにゼロ日付背中を配置する必要があります。

MySQLに接続するプログラマは、null、0000-00-00、および有効な日付を処理する必要があります。0000-00-00をnullに変更することは実行可能なオプションではありません。データベースに書き戻すために日付が0000-00-00であると予想されたかどうかを判断できなくなるためです。

0000-00-00の場合は、日付値を文字列として確認し、それを( "y"、1)、または( "yyyy-MM-dd"、0001-01-01)、または無効な値に変更することをお勧めしますMySQLの日付(1000年未満、iirc)。MySQLには別の「機能」があります。低い日付は自動的に0000-00-00に変換されます。

私の提案はクラッジだと気づきました。しかし、MySQLの日付処理も同様です。そして、2つのクラッジはそれを正しくしません。問題の事実は、多くのプログラマーがMySQLゼロ日付を永遠に処理しなければならないということです


9

次のステートメントをJDBC-mysqlプロトコルに追加します。

?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

例えば:

jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

5
このアプローチには注意してください。それは魅力のように機能しますが、私たちの運用サーバーを停止しました(ただし、開発環境では完全に動作しました...)。&は一部のコンテキストでは特殊文字として解釈されるため、文字列を引用符で
囲む

6

0000-00-00 00:00:00またはのような偽の日付を使用する代わりに0001-01-01 00:00:00(後者は有効な日付であるため、受け入れる必要があります)、NULL値を許可するようにデータベーススキーマを変更します。

ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL

3

extemeのターンアラウンドとして、日付列を変更したり、値を更新したりできない場合、またはこれらの変更が行われているときに、case / whenを使用して選択を行うことができます。

SELECT CASE ModificationDate WHEN '0000-00-00 00:00:00' THEN '1970-01-01 01:00:00' ELSE ModificationDate END AS ModificationDate FROM Project WHERE projectId=1;

1

私はこの問題に取り組み、@ Kushanによって提供されたURL連結ソリューションを上記の受け入れられた回答に実装しました。ローカルのMySqlインスタンスで機能しました。しかし、自分のPlay / ScalaアプリをHerokuにデプロイすると、機能しなくなりました。Herokuは、ユーザーに提供するDB URLにいくつかの引数を連結します。この解決策は、Herokuが "?"を使用して連結しているためです。独自の引数セットの前では機能しません。しかし、同じように機能するように見える別の解決策を見つけました。

SET sql_mode = 'NO_ZERO_DATE';

これを自分のテーブルの説明に入れて、「0000-00-00 00:00:00」がjava.sql.Timestampとして表現できないという問題を解決しました


1

あなたはこのように試すことができます

ArrayList<String> dtlst = new ArrayList<String>();
String qry1 = "select dt_tracker from gs";

Statement prepst = conn.createStatement();
ResultSet rst = prepst.executeQuery(qry1);
while(rst.next())
{
    String dt = "";
    try
    {
        dt = rst.getDate("dt_tracker")+" "+rst.getTime("dt_tracker");
    }
    catch(Exception e)
    {
        dt = "0000-00-00 00:00:00";
    }

    dtlst.add(dt);
}

0

0000年はなく、00月または00日はありません。

0001-01-01 00:00:00

年0はいくつかの標準で定義されていますが、有用なIMHOよりも混乱する可能性があります。


2
はい、年0000があります。その年は0であり、年-1と年-1000があります。このグレゴリオ暦またはこのAnno Dominiを見たことがない、特にグレゴリオ暦には年のゼロはありませんが、isoには0
botenvouwer

@sirwilliam興味深い資格をありがとうございます。OPは0年をNULLまたは存在しないものとして扱うことを望んでいたようです。
Peter Lawrey 2013年

1
MySQLでは0000-00-00 00:00:00は0と同じです。レガシーコードでは、これに依存するクエリがいくつかある場合があります。
JuhaPalomäki2015年


0

私はこれが遅い答えになることを知っていますが、ここが最も正しい答えです。

MySQLデータベースで、timestampデフォルト値をに変更しますCURRENT_TIMESTAMP。偽の値を持つ古いレコードがある場合は、手動で修正する必要があります。


これも役に立ちません。
Sunil Sharma

0

不要な場合は、mysqlテーブルの列から「nullでない」プロパティを削除できます。「not null」プロパティを削除すると、「0000-00-00 00:00:00」変換の必要がなくなり、問題は解消されます。

少なくとも私のために働いた。


-2

これは、logstashエラーを介してデータをポンプする例外の下でこれを取得している人にとって完全に役立つと思います:logstash.inputs.jdbc-JDBCクエリ実行時の例外{:exception =>#}

回答:jdbc:mysql:// localhost:3306 / database_name?zeroDateTimeBehavior = convertToNull "

またはmysqlで作業している場合

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.