developer tip

DATE 또는 DATETIME에 대한 기본값을 설정할 때 mysql 오류

optionbox 2020. 8. 16. 20:12
반응형

DATE 또는 DATETIME에 대한 기본값을 설정할 때 mysql 오류


MySql Server 5.7.11 및 다음 문장을 실행하고 있습니다.

updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

한다 하지 작업. 오류 제공 :

ERROR 1067 (42000): Invalid default value for 'updated'

그러나 다음은 다음과 같습니다.

updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

그냥 작동합니다 .

DATE도 마찬가지입니다.

A와 (!) 참고 , 그것은에서 언급 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')의 "0"값으로 변환됩니다.

mysql 문서의 두 번째 인용문을 고려할 때 누구든지 그 오류가 발생하는 이유를 알 수 있습니까?


이 오류는 최신 MYSQL 5.7 문서에 따라 엄격 모드가 될 수있는 SQL 모드 때문입니다.

MySQL 문서 5.7은 다음과 같이 말합니다 .

Strict 모드는 서버가 '0000-00-00'을 유효한 날짜로 허용하는지 여부에 영향을줍니다. Strict 모드를 사용하지 않으면 '0000-00-00'이 허용되고 삽입시 경고가 생성되지 않습니다. 엄격 모드가 활성화 된 경우 '0000-00-00'은 허용되지 않으며 IGNORE도 제공되지 않는 한 삽입시 오류가 발생합니다. 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:00mysql 구성 파일 또는 명령으로 STRICT_TRANS_TABLES 모드를 비활성화해야합니다.

명령으로

SET sql_mode = '';

또는

SET GLOBAL sql_mode = '';

키워드를 사용 GLOBAL하려면 슈퍼 권한이 필요하며 해당 시점부터 모든 클라이언트가 연결하는 작업에 영향을줍니다.

위의 내용이 작동하지 않으면 /etc/mysql/my.cnf우분투로 이동하여 주석 처리하십시오.STRICT_TRANS_TABLES

영구적 서버 시작시 SQL 모드를 설정하려는 경우 또한, 다음을 포함 SET sql_mode=''my.cnf리눅스 나 맥 OS에. Windows의 경우 이것은 my.ini파일 에서 수행되어야 합니다.

노트

그러나 엄격 모드는 MYSQL 5.6에서 기본적으로 활성화되지 않습니다. 따라서 그것은에 따라 오류를 생성하지 않습니다 MYSQL 6 문서를 말한다

MySQL에서는 "0"값 '0000-00-00'을 "더미 날짜"로 저장할 수 있습니다. 이는 경우에 따라 NULL 값을 사용하는 것보다 더 편리하며 데이터 및 인덱스 공간을 적게 사용합니다. '0000-00-00'을 허용하지 않으려면 NO_ZERO_DATE SQL 모드를 활성화하십시오.

최신 정보

@ Dylan-Su가 말한 버그 문제와 관련하여 :

나는 이것이 시간이 지남에 따라 MYSQL이 진화하는 방식의 버그라고 생각하지 않습니다. 이로 인해 제품의 추가 개선에 따라 일부가 변경됩니다.

그러나 NOW()기능 에 관한 또 다른 관련 버그 보고서가 있습니다.

Datetime 필드는 기본 NOW ()를 허용하지 않습니다.

또 다른 유용한 참고 사항 [ TIMESTAMP 및 DATETIME에 대한 자동 초기화 및 업데이트 참조 ]

MySQL 5.6.5부터 TIMESTAMP 및 DATETIME 열은 자동으로 초기화되고 현재 날짜 및 시간 (즉, 현재 타임 스탬프)으로 업데이트 될 수 있습니다. 5.6.5 이전에는 TIMESTAMP 및 테이블 당 최대 하나의 TIMESTAMP 열에 대해서만 적용됩니다. 다음 노트에서는 먼저 MySQL 5.6.5 이상에 대한 자동 초기화 및 업데이트에 대해 설명하고 5.6.5 이전 버전의 차이점에 대해 설명합니다.

NO_ZERO_DATE에 대한 업데이트

MySQL 5.7.4부터이 모드는 더 이상 사용되지 않습니다. 이전 버전의 경우 구성 파일에서 해당 줄을 주석 처리해야합니다. NO_ZERO_DATE에 대한 MySQL 5.7 문서 참조


MySql 5.7.14를 사용하는 WAMP 3.0.6에서이 오류가 발생했습니다.

해결책 :

파일의 70 행 (ini 파일이 변경되지 않은 경우)을 다음에서 변경 c:\wamp\bin\mysql\mysql5.7.14\my.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"

모든 서비스를 다시 시작하십시오.

This will disable strict mode. As per the documentation, “strict mode” means a mode with either or both STRICT_TRANS_TABLES or STRICT_ALL_TABLES enabled. The documentation says:

"The default SQL mode in MySQL 5.7 includes these modes: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION."


I got into a situation where the data was mixed between NULL and 0000-00-00 for a date field. But I did not know how to update the '0000-00-00' to NULL, because

 update my_table set my_date_field=NULL where my_date_field='0000-00-00'

is not allowed any more. My workaround was quite simple:

update my_table set my_date_field=NULL where my_date_field<'1000-01-01'

because all the incorrect my_date_field values (whether correct dates or not) were from before this date.


Config syntax issue

On some versions of MYSQL (tested 5.7.*) under *nix systems you should use this syntax:

[mysqld]

sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"

These won't work:

dash no quotes

sql-mode=NO_ENGINE_SUBSTITUTION

underscore no quotes

sql_mode=NO_ENGINE_SUBSTITUTION

underscore and quotes

sql_mode="NO_ENGINE_SUBSTITUTION"

A more complete review of config values and sql-mode:

How to setup permanent Sql Mode flags


Just add the line: sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

inside file: /etc/mysql/mysql.conf.d/mysqld.cnf

then sudo service mysql restart


First select current session sql_mode:

SELECT @@SESSION.sql_mode;

Then you will get something like that default value:

'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'

and then set sql_mode without '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';

If you have grants, you can do it also for GLOBAL:

SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';

It works for 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)

You can create a SQLFiddle to recreate your issue.

http://sqlfiddle.com/

If it works for MySQL 5.6 and 5.7.8, but fails on 5.7.11. Then it probably be a regression bug for 5.7.11.


This answer it's just for MySQL 5.7:

Best is not really set in blank the sql_mode, instead use in PHP a session variable with:

SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

So at least you keep the another default values.

It's crazy that mysql documentation is not clear, you need delete this defeault values in sql_mode:

NO_ZERO_IN_DATE,NO_ZERO_DATE, I understand, but in the future versiones this will be discontinued.

STRICT_ALL_TABLES, with this, before parameters will be ignored, so you need delete it too.

Finally TRADITIONAL too, but documentation speak about this parameter: “give an error instead of a warning” when inserting an incorrect value into a column", with this parameter, dates with zero values is not inserted, but without yes.

MySQL is not really organised with these parameters and combinations.


To solve the problem with MySQL Workbench (After applying the solution on the server side) :

Remove SQL_MODE to TRADITIONAL in the preferences panel.

enter image description here


Option combinations for mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64).

Doesn't throw:

STRICT_TRANS_TABLES + NO_ZERO_DATE

Throws:

STRICT_TRANS_TABLES + NO_ZERO_IN_DATE

My settings in /etc/mysql/my.cnf on Ubuntu:

[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

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';

참고URL : https://stackoverflow.com/questions/36374335/error-in-mysql-when-setting-default-value-for-date-or-datetime

반응형