[mysql] 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"

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

이것은 엄격 모드를 비활성화합니다. 설명서에 따라 “엄격 모드”는 둘 중 하나 또는 둘 다 STRICT_TRANS_TABLES또는 STRICT_ALL_TABLES활성화 된 모드를 의미합니다 . 문서는 말합니다 :

“MySQL 5.7의 기본 SQL 모드에는 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 모드가 포함됩니다.”


답변

날짜 필드에 대해 데이터가 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값 (올바른 날짜이든 아니든)이이 날짜 이전의 것이기 때문 입니다.


답변

구성 구문 문제

* nix 시스템의 일부 MYSQL 버전 (5.7. * 테스트)에서는 다음 구문을 사용해야합니다.

[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-mode에 대한보다 완전한 검토 :

영구 SQL 모드 플래그를 설정하는 방법


답변

먼저 현재 세션 선택 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 = '...';


답변

다음 줄을 추가하십시오. sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

내부 파일 : /etc/mysql/mysql.conf.d/mysqld.cnf

그때 sudo service mysql restart


답변

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을 만들어 문제를 재현 할 수 있습니다.

http://sqlfiddle.com/

MySQL 5.6 및 5.7.8에서는 작동하지만 5.7.11에서는 실패합니다. 그렇다면 아마도 5.7.11의 회귀 버그 일 것입니다.