MySQL:ERROR1067-「end_time」のデフォルト値が無効です



Mysql Error 1067 Invalid Default Value Forend_time



Mysqlバージョン:5.7.24

まず、問題の説明
次のように、SQLステートメントを実行するテーブルを作成します。



create table train_record ( id int(11) not NULL AUTO_INCREMENT, User_name VARCHAR(20) NOT NULL COMMENT 'username', Train_name TINYINT(1) DEFAULT'2' NOT NULL COMMENT' training program, 1 active training 2 guided training', Start_time TIMESTAMP NOT NULL COMMENT 'start time', End_time TIMESTAMP NOT NULL COMMENT 'end time', Train_duration INT(4) NOT NULL COMMENT 'training duration', Train_times int(4) DEFAULT'1' NOT NULL COMMENT' number of trainings, 1-16 times 2-32 times 3-48 times 4-64 times 5-80 times 6-96 times', Repeat_time TINYINT(1) DEFAULT'1' NOT NULL COMMENT' Repeat the number of times after clicking, 1-1 times 2-2 times 3-3 times', Volume int(3) DEFAULT'0' NOT NULL COMMENT 'volume', Play_random TINYINT(1) DEFAULT'1' NOT NULL COMMENT' is random, 1 is 0 no', PRIMARY KEY(id) ) COMMENT 'training record table'

SQLエラーの結果を実行します。

1067-'end_time 'のデフォルト値が無効です、時間:0.000000s



理由:mysqlは5.7から始まり、デフォルトはstrictモードであり、SQL92仕様に厳密に準拠しています。

mysql> show variables like 'explicit_defaults_for_timestamp'

実行結果:変数explicit_defaults_for_timestampの値がオフになっています。

mysql> show variables like 'sql_mode'

結果は次のとおりです。



ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
  1. プロテスト、1つのフィールドのみがTIMESTAMPタイプに設定されている場合、テーブルを作成します。デフォルトでは、null属性は指定されていません。フィールドは、自動的にNOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP属性を追加します。このフィールドにヌル値を挿入すると、このフィールドはCURRENT_TIMESTAMP(現在の時刻)値に設定されます。

説明:DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPは、新しいレコードを作成し、既存のレコードを変更するときに、このデータ列が更新されることを意味します。

  1. プロテスト、TIMESTAMPタイプを指定するフィールドが複数ある場合はテーブルを作成し、null属性が指定されていないか、デフォルト値が設定されていない場合、2番目のTIMESTAMPフィールドは無効なエラーを報告します。
    それの訳は:
    最初のTIMESTAMPフィールドには、DEFAULTCURRENT_TIMESTAMP属性とONUPDATECURRENT_TIMESTAMP属性が自動的に追加されます。
    最初のTIMESTAMPの後のフィールドには、デフォルトの「0000-00-0000:00:00」属性が自動的に追加されます。 sql_mode変数の5.7バージョンにはNO_ZERO_DATEが含まれており、これは「0000-00-0000:00:00」形式が不正であることを示しています。これは厳密モードに関連しています。

第二に、解決策
グローバル変数explicit_defaults_for_timestampを変更します

mysql> set global explicit_defaults_for_timestamp = ON

説明:mysqlを終了して再入力する必要があります。変数が有効になります。
この時点で、create table sqlステートメントを実行すると、プロテストの実行が成功します。

  1. デフォルト値が指定されていないため、start_time値とend_time値はnullになり、挿入操作が実行されます。 strictモードのため、実行ステートメントはエラーを報告します。エラーステートメントは次のとおりです。

1364-フィールド 'start_time'にはデフォルト値がありません。時間:0.000000s

値が0000-00-0000:00:00に設定されている場合、挿入操作が実行され、エラーは次のようになります。

1292-日付時刻の値が正しくありません:行1の列 'start_time'の '0000-00-00 00:00:00'時間:0.001000s

このとき、グローバル変数sql_modeを変更し、NO_ZERO_IN_DATE、NO_ZERO_DATEを削除し、次のようにsqlステートメントを実行する必要があります。

mysql> set global sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

次に、挿入操作を実行すると、プロテストが成功します。

insert into train_record ( user_name, train_name, start_time, end_time, train_duration, train_times, repeat_time, volume, play_random) VALUES( 'liulin', 2, '0000-00-00 00:00:00', '0000-00-00 00:00:00', 30, 4, 3, 50, 1)

したがって、sqlステートメントを作成するときは、次に示すように、デフォルトの「0000-00-0000:00:00」をstart_timeフィールドとend_timeフィールドのnotnull属性に追加します。

Start_time timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Create time', End_time timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Create time',

したがって、TIMESTAMPフィールドの値が空の場合、デフォルトの挿入は0000-00-00 00:00:00であり、実行ステートメントはエラーを報告しません。

  1. start_timeフィールドとend_timeフィールドのnull以外が削除された場合は、sqlステートメントを実行すると、2つのフィールドにDEFAULTDULL属性が自動的に追加されます。挿入操作が実行されるときに、TIMESTAMPフィールド値がnullの場合、レコードはnullであり、次にCURRENT_TIMESTAMP(現在の時刻)値ではありません。

第三に、まとめ

  1. 以前、会社のプロジェクトはMySQLバージョン5.6.42を使用していました。バックアップがローカルデータベースに移行されたときに、0000-00-0000:00:00の形式の不正な日付が検出されました。 SQLファイルをインポートしているため、バッチ置換は少し面倒です。そのため、sql_modeのNO_ZERO_IN_DATE、NO_ZERO_DATEだけを削除できます。

  2. Explicit_default_for_timestampの説明については、mysqlの公式Webサイトを参照してください。 サーバーシステム変数 この記事では、右上隅を切り替えて、さまざまなmysqlバージョンのシステム変数を表示できます。

  3. DateTimeタイプは、ビジネスが秒単位で正確である必要がある場合にも考慮することができます。