web-dev-qa-db-ja.com

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

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

 (`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を取得する方法はありますか?

137

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

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

283
Kushan

「日付」「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のゼロ日付foreverを処理する必要があります。

15

次のステートメントを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
8

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

ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL
6
npe

極端なターンアラウンドとして、日付列の変更や値の更新ができない場合、またはこれらの変更が行われている間に、ケース/タイミングを使用して選択を行うことができます。

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;
3
VCeron

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

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);
}
1
13hola

私はこの問題に取り組み、上記の受け入れられた回答で@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
Aqume

フィールドをcharとしてキャストするだけです

例:updateateとしてのcharとしてのcast(updatedate)

0

0000年はなく、00月も00日もありません。試してみることをお勧めします

0001-01-01 00:00:00

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

0
Peter Lawrey

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

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

0
Celik

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

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

0
PeakGen