私はMySqlサーバー5.7.11とこの文章を実行しています。
updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
is動作していません。エラーを出す:
ERROR 1067 (42000): Invalid default value for 'updated'
しかし、以下:
updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00'
は動作します。
DATEの場合も同じです。
サイドノートとして、 mysqlのドキュメント に記載されています。
DATE型は、日付部分はあるが時間部分はない値に使用されます。 MySQLは 'YYYY-MM-DD'形式でDATE値を取得して表示します。サポートされている範囲は '1000-01-01'から '9999-12-31'です。
彼らが言っても:
無効なDATE、DATETIME、またはTIMESTAMP値は、適切なタイプの「ゼロ」値( '0000-00-00'または '0000-00-00 00:00:00')に変換されます。
Mysqlドキュメントからの2番目の引用も考慮に入れて、それがなぜそのエラーを与えているのか誰かに私に知らせてもらえますか?
このエラーは、最新のMYSQL 5.7ドキュメントのとおり、厳密モードである可能性があるSQLモードのためです。
厳密モードは、サーバーが有効な日付として '0000-00-00'を許可するかどうかに影響します。厳密モードが有効になっていない場合は '0000-00-00'が許可され、挿入は警告を生成しません。厳密モードが有効な場合、IGNOREも与えられていない限り、 '0000-00-00'は許可されず、挿入はエラーを生成します。 INSERT IGNOREおよびUPDATE IGNOREの場合、 '0000-00-00'が許可され、挿入によって警告が生成されます。
MYSQLモードをチェックする
SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session
STRICT_TRANS_TABLESモードを無効にする
ただし、フォーマット0000-00-00 00:00:00
を許可するには、mysql設定ファイルまたはコマンドでSTRICT_TRANS_TABLESモードを無効にする必要があります。
コマンドによる
SET sql_mode = '';
または
SET GLOBAL sql_mode = '';
キーワードGLOBAL
を使うことは超特権を必要とし、それはその時から全てのクライアントが接続する操作に影響します
上記の方法でうまくいかない場合は、(ubuntuによる)/etc/mysql/my.cnf
に行き、STRICT_TRANS_TABLES
をコメントアウトしてください。
また、サーバの起動時にSQLモードを永続的に設定したい場合は、LinuxまたはMacOSのSET sql_mode=''
にmy.cnf
を含めます。 Windowsの場合、これはmy.ini
ファイルで行わなければなりません。
注
ただし、MYSQL 5.6では、厳密モードはデフォルトで有効になっていません。そのため、 MYSQL 6のドキュメントのようにエラーは発生しません
MySQLでは、「ダミーの日付」として「0000-00-00」の「ゼロ」値を格納することができます。これは、NULL値を使用するよりも便利な場合があり、データとインデックススペースの使用量が少なくなります。 '0000-00-00'を禁止するには、NO_ZERO_DATE SQLモードを有効にします。
UPDATE
@ Dylan-Suが言ったバグの問題に関して:
私はこれがバグであるとは思わない。MYSQLが時間の経過とともに進化していくのは、製品のさらなる改良に基づいていくつかのことが変更されるからである。
しかし、私はNOW()
関数に関する別の関連バグレポートを持っています
他の便利な注意事項[ TIMESTAMPとDATETIMEの自動初期化と更新 ]を参照してください。
MySQL 5.6.5以降、TIMESTAMP列とDATETIME列は自動的に初期化され、現在の日時(つまり現在のタイムスタンプ)に更新されるようになりました。 5.6.5より前では、これはTIMESTAMPと、テーブルごとに最大1つのTIMESTAMP列にのみ当てはまります。以下の注記では、まずMySQL 5.6.5以降の自動初期化と更新について説明し、次に5.6.5より前のバージョンの違いについて説明します。
NO_ZERO_DATEに関する更新
MySQL 5.7.4では、このモードは推奨されていません。以前のバージョンでは、設定ファイルのそれぞれの行をコメントアウトする必要があります。 MySQL 5.7のNO_ZERO_DATEドキュメントを参照
私はMySql 5.7.14とWAMP 3.0.6でこのエラーがありました。
解決策:
c:\wamp\bin\mysql\mysql5.7.14\my.ini
ファイルの70行目(iniファイルが変更されていない場合)を
sql-mode= "STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
に
sql-mode="ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
そしてすべてのサービスを再起動します。
これは厳密モードを無効にします。ドキュメントによると、「厳密モード」はSTRICT_TRANS_TABLES
またはSTRICT_ALL_TABLES
のいずれかまたは両方が有効になっているモードを意味します。 のドキュメント には次のように書かれています。
msgstr "" "MySQL 5.7のデフォルトSQLモードにはこれらのモードが含まれます:ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_AUTO_CREATE_USER、そしてNO_ENGINE_SUBSTITUTION
日付フィールドにNULLと0000-00-00の間でデータが混在している状況に陥りました。しかし、 '0000-00-00'をNULLに更新する方法がわかりませんでした。
update my_table set my_date_field=NULL where my_date_field='0000-00-00'
これ以上許可されていません。私の回避策は非常に簡単でした。
update my_table set my_date_field=NULL where my_date_field<'1000-01-01'
すべての不正確なmy_date_field
値(正しい日付であるかどうかにかかわらず)はこの日付より前のものであるためです。
MIXQLのいくつかのバージョン(テスト済み5.7。*)では* nixシステムの下であなたはこの構文を使うべきです:
[mysqld]
sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"
ダッシュ引用符なし
sql-mode=NO_ENGINE_SUBSTITUTION
二重引用符なし
sql_mode=NO_ENGINE_SUBSTITUTION
アンダースコアと引用符
sql_mode="NO_ENGINE_SUBSTITUTION"
設定値とSQLモードのより完全なレビュー:
次の行を追加するだけです:sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
ファイルの中:/etc/mysql/mysql.conf.d/mysqld.cnf
それからSudo service mysql restart
まず現在のセッションを選択しますsql_mode
:
SELECT @@SESSION.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'
sql_mode
を指定せずに'NO_ZERO_DATE'
を設定します。
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
助成金がある場合は、GLOBAL
に対しても付与できます。
SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';
5.7.8で動作します。
mysql> create table t1(updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00');
Query OK, 0 rows affected (0.01 sec)
mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.8-rc |
+-----------+
1 row in set (0.00 sec)
あなたはあなたの問題を再現するためにSQLFiddleを作成することができます。
MySQL 5.6および5.7.8で動作しますが、5.7.11で失敗した場合。それでそれはおそらく5.7.11のための回帰バグです。
この答えはMySQL 5.7用です。
Sql_modeを実際に空白に設定するのではなく、代わりにPHPでセッション変数を使用してください。
SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
だから少なくともあなたは別のデフォルト値を維持する。
Mysqlのドキュメントがはっきりしていないのはおかしいです、あなたはsql_modeでこのディフェンス値を削除する必要があります:
NO_ZERO_IN_DATE、NO_ZERO_DATE、わかっていますが、将来のバージョンでは廃止される予定です。
STRICT_ALL_TABLES、これで、パラメータが無視される前に、あなたもそれを削除する必要があります。
最後にTRADITIONALも同様ですが、ドキュメントはこのパラメータについて語っています。列に誤った値を挿入するときに「警告の代わりにエラーを出す」、このパラメータではゼロ値の日付は挿入されず.
MySQLは実際にはこれらのパラメータと組み合わせで構成されていません。
set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64)
のオプションの組み合わせ。
投げません:
STRICT_TRANS_TABLES
+ NO_ZERO_DATE
スローします。
STRICT_TRANS_TABLES
+ NO_ZERO_IN_DATE
Ubuntuの/etc/mysql/my.cnf
で私の設定:
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"