2

こんにちは私はSQLデータベースにサーブレット経由で日付を挿入しようとしています。投稿されたフィールドの誕生日が空の場合は、0000-00-00を挿入する必要があります

しかし、これは少し複雑です。

私はこのようにそれをしました、そしてそれは働きます:

if (birthdate == null) {
            ps_employee.setInt(4, 0); //ps_employee is my PreparedStatement
        } else {
            ps_employee.setDate(4, birthdate);
        }

postフィールドに値がない場合、birthdayはnullです。それ以外の場合、誕生日には有効なjava.sql.dateオブジェクトが含まれます。

上記のコードは機能しますが、SQLに「誕生日のデータが切り捨てられました」という警告が表示されます。

0000-00-00の日付を挿入するより良い方法はありますか?

ご協力いただきありがとうございます..

4

7 に答える 7

3
  String query="INSERT INTO tablename values(?) "
  Connection connection = get the dbconn;
  PreparedStatement preparedStatement= connection.prepareStatement(query);      
  preparedStatement.setNull(0, java.sql.Types.DATE)
于 2012-09-25T21:25:15.073 に答える
2

送信されたフィールドが空の場合はnull、今後20年間データを使用するすべてのアプリケーションでチェックする必要のある魔法の値ではなく、保存する必要があります。

null出力時に「0000-00-00」(またはその他)に変換します。

于 2012-09-25T21:25:38.817 に答える
2

このソリューションは、システムのデータ整合性要件に依存します。

2つ(そして2つだけ)の選択肢があります:

  1. システムの設計(設計がありますよね?)では、すべてのレコードに有効な誕生日が必要です。この場合、これを強制するのはUIの責任です。コードがnullの日付を受け取ることはなく、受け取った場合に例外をスローすることは正当化されます。これにより、問題が解消されます。
  2. 場合によっては、生年月日が欠落していてもかまいません。この場合、null値を許可するようにテーブル定義を変更する必要があります。

最後にやりたいことは、NULLの代用として特別な日付値を作成することです。列がNULLでないという事実は、上記のケース(1)が当てはまり、特別な日付が実際にシステムのデータ整合性の不変条件に違反していることを示しています。コードの保守を任務とする将来のプログラマーは皆、あなたの名前を呪うでしょう。

于 2012-09-25T21:50:09.633 に答える
1

良い解決策はありません

データベースで空の日時値を処理する方法の問題には、適切な解決策がありません。

NULLを避けてください

クリス・デイト博士が「SQL標準のガイド」などで説明しているように、NULLは非常に悪夢です。一般的に、可能な限り避ける必要があります。SQLデータベースでは、これは各列を次のように宣言することを意味しますNOT NULL(これをデフォルトにする方法があればいいのにと思います)。賢明な場合は、ある種のデフォルト値を設定します。

日時に適切なデフォルト値がない

ただし、日時値のデフォルト値を設定すると、非常に混乱する可能性があります。SQL標準もJDBC/java.sql。*も、特定の値を「空」のフラグとして定義していません。

Java 8以降に組み込まれているjava.timeフレームワークは、最小値と最大値を、、、、およびクラスの定数としてInstant定義LocalDateTimeLocalDateますLocalTime。これらの値は、解決の重大な問題を除いて、フラグ値として機能する可能性があります。これらのjava.timeクラスはナノ秒に解決されますが、多くのデータベースはPostgresのマイクロ秒などのより大きな粒度を持っています。最小値と最大値は非常に極端であるため、より小さな粒度に切り捨てると、その意味が変わります。

ゼロ値

直感的に、ゼロ値の日時、 0000-00-00 00:00:00.0//を検討すると考えるかもしれません。それほど単純ではありません。0000-00-0000:00:00.0

ゼロ月/日なし

まず、の月00や日などはありません00。さて、0000-01-011月1日に変更できます。

ゼロ年なし

次号:そのような年はありません0000。すべてのデータベースについてはわかりませんが、少なくともPostgresではそのようなゼロ年はありません。このような値を挿入しようとすると、エラーが発生します。

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES (  '0000-01-01 00:00:00.0Z' ) ;

…エラーをスローします:

ERROR:  date/time field value out of range: "0000-01-01 00:00:00.0Z"
LINE 2: VALUES (  '0000-01-01 00:00:00.0Z' ) ;
                  ^
********** Error **********

00001年目に変更し0001ます。

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES (  '0001-01-01 00:00:00.0Z' ) ;

SET TIME ZONE 'UTC' ;

TABLE moment_ ;

0001-01-01 00:00:00 + 00

BCその数は、対AD時代の要点です。ADからBCに移動する動作を確認するために、1時間を減算してみましょう。ちなみに、などの文字列BCはロケールに依存するため、状況によって異なる場合があります。また、この日時操作を正しく完了するには、タイムゾーンをUTCに設定する必要があることに注意してください。

SET TIME ZONE 'UTC' ;

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES ( TIMESTAMP '0001-01-01 00:00:00.0Z' - INTERVAL '1 hour' ) ;

SET TIME ZONE 'UTC' ;

TABLE moment_ ;

結果は年0001 BCなので、からにジャンプ00010001 BCます。年ゼロはありません0000

"0001-12-31 23:00:00 + 00 BC"

したがって、特定のフラグ値を使用することにした場合、真のゼロ値を使用することはできませんが、1年目のADの1月1日であるゼロに近い値を使用することはできます。'0001-01-01 00:00:00.0Z'

タイムゾーン

この特別なフラグ値を使用する場合は、タイムゾーンに注意する必要があります。

文字列を渡すとき、SQLセッションの現在のデフォルトのタイムゾーンが暗黙的に適用されます(少なくともPostgresでは)。

NULLの並べ替え

私自身の仕事では、実際にほぼすべての列をNULLではなく、デフォルトを設定しています。ただし、実行可能なフラグ値がないため、日時列は例外です。そして、私はこれに苦しんでいます。具体的には、 SQL標準ではNULLのデフォルトのソート順が明示的に定義されていないNULLS FIRSTため、 /NULLS LAST修飾子の使用方法を難しい方法で学びました。

于 2016-02-03T02:33:31.563 に答える
0

エラーが発生する理由は、無効な日付を挿入しようとしているためです。0月と0日というものはありません。MySQLはそれを日付として受け入れません。

他のユーザーが説明しているようにNULLを使用するか、「1100-01-01」などの定義した最小ベースライン日付を使用してください

于 2012-09-25T21:27:13.980 に答える
0

私がそれを行う方法は、列のデフォルト値を使用することです。タイプに応じて、デフォルトを「0000-00-00」または「0000-00-0000:00:00」に設定します。

DBでデフォルト値を設定したら、挿入ステートメントでそのフィールドを指定しないでください。nullを許可しない列に対してこれを行うことができ、それでもMySQLの疑似null日付で挿入されます。

その場合、zeroDateを読み取ることができないため、このパラメーターもSQL接続文字列に追加する必要があります。

zeroDateTimeBehavior = convertToNull

最終的には、これらの日付をJavaではnullとして、MySQLデータベースでは0000-00-00として処理します。

于 2013-10-09T23:42:06.510 に答える
0

データでNULLが許可されているが、SQLテーブルでは許可されていない場合(たとえば、複合キーの日付部分)、一般的に受け入れられている「空の」値(GUIツールはこの値を使用)を使用して、デフォルト/空白の日付を表すことができます。ここに例があります:

private static final String EMPTY_MYSQL_DATE = "0000-00-00 00:00:00";    
...
if(someDateObj == null) {
    preparedStatement.setString(++psIndex, EMPTY_MYSQL_DATE);
} else {
    preparedStatement.setTimestamp(++psIndex, new Timestamp(someDateObj.getTime()));
}
于 2016-02-01T18:38:46.853 に答える