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


124

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 문서의 두 번째 인용문을 고려할 때 누구든지 그 오류가 발생하는 이유를 알 수 있습니까?


11
무의미한 기본값을 원하는 이유는 무엇입니까? 날짜를 알 수없는 경우 정확히 그 이유 NULL입니다.
Tom H

참고 : 이것은 SQL Fiddle의 버전 5.6 ( sqlfiddle.com/#!9/02c98) 에서 작동합니다 .
Gordon Linoff

@Karlos는 업데이트 된 답변을 확인하십시오.
geeksal

답변:


209

이 오류는 최신 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 문서 참조


5
업데이트 IGNORE는 내가 찾던 것입니다 👍🏻
Afanasii Kurakin

2
잘못된. 나는이 STRICT_TRANS_TABLES내 두 MySQL의 인스턴스, 로컬 및 서버. 그러나 0000-00-00로컬 인스턴스에는 쉽게 삽입 할 수 있지만 서버 인스턴스에는 삽입 할 수 없습니다. 오류가 발생합니다. 왜? 내 서버 MySQL 구성이 NO_ZERO_DATE활성화 되었기 때문 입니다. 그리고 내 지역은 그것을 가지고 있지 않습니다.
Green

ok @Green 해당되는 경우 답변을 파악하고 업데이트
하겠습니다

4
제 경우에는 'SET sql_mode = ""'가 작동하지 않았습니다. 'SET GLOBAL sql_mode = "";' 나를 위해 일했습니다.
arjen Stens

또한 NO_ZERO_DATE제거되어야합니다
Preshan Pradeepa

18

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 모드가 포함됩니다."


14

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


2
완벽한 빠른 솔루션. <'0000-01-01'물론 유효한 날짜이기 때문에 실제로 사용할 수도 있습니다 .
Ricky McMaster 2018

5

구성 구문 문제

* 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 모드 플래그를 설정하는 방법


5

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

4

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

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

그때 sudo service mysql restart


1
5.7.23에서 작동합니다.
user2513149

1
나는 아마 SELECT @@SESSION.sql_mode;먼저 제안 하고, 그들이 당신에게 제공하는 것에서 NO_ZERO_IN_DATE, NO_ZERO_DATE 및 STRICT_TRANS_TABLES를 제거합니다. 이렇게하면 활성화 한 다른 설정을 유지할 수 있습니다. 내 SQL 모드에 대해 설정된 두 항목보다 더 많은 것이 있습니다. 그들 모두가 무엇을하는지 모르지만이 시점에서 그들을 제거 할 위험을 감수하고 싶지 않습니다.
Radley Sustaire

2

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의 회귀 버그 일 것입니다.


1

MySQL Workbench로 문제를 해결하려면 (서버 측에 솔루션을 적용한 후) :

환경 설정 패널에서 SQL_MODE를 TRADITIONAL로 제거하십시오.

여기에 이미지 설명 입력


1

이 답변은 MySQL 5.7 전용입니다.

Best는 실제로 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와 함께 매개 변수가 무시되기 전에 매개 변수도 삭제해야합니다.

마지막으로 전통적이지만 문서에서는이 매개 변수에 대해 설명합니다. "열에 잘못된 값을 삽입 할 때"경고 대신 오류를주십시오 "",이 매개 변수를 사용하면 값이 0 인 날짜는 삽입되지 않지만 예는 없습니다.

MySQL은 실제로 이러한 매개 변수와 조합으로 구성되어 있지 않습니다.


0

옵션 조합 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

/etc/mysql/my.cnfUbuntu의 내 설정 :

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

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

0

in diretory xamp / mysql / bin "my.ini"를 열고 행을 변경하십시오. Sql_node for->

"sql_mode = NO_ENGINE_SUBSTITUTION, NO_ZERO_DATE"

'NO_ZERO_IN_DATE'삭제


stackoverflow에 오신 것을 환영합니다. 적절한 코드 형식을 사용하여 답변의 가독성을 높이십시오.
vlizana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.