Loading...
MySQL 9.5 Reference Manual 9.5의 7.1.11 Server SQL Modes의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MySQL 서버는 서로 다른 SQL 모드로 동작할 수 있으며,
sql_mode 시스템 변수의 값에 따라
각 클라이언트에 서로 다르게 이러한 모드를 적용할 수 있습니다.
DBA는 사이트 서버 운영 요구사항에 맞추어 글로벌 SQL 모드를 설정할 수 있고,
각 애플리케이션은 자신의 요구사항에 맞추어 세션 SQL 모드를 설정할 수 있습니다.
모드는 MySQL이 지원하는 SQL 구문과 수행하는 데이터 검증 검사를 제어합니다. 이는 MySQL을 다양한 환경에서 더 쉽게 사용하고, MySQL을 다른 데이터베이스 서버와 함께 사용할 때도 더 쉽게 해 줍니다.
MySQL에서 서버 SQL 모드에 대해 자주 묻는 질문의 답변은 Section A.3, “MySQL 9.5 FAQ: Server SQL Mode”를 참조하십시오.
InnoDB 테이블을 사용할 때에는
innodb_strict_mode 시스템 변수도 고려하십시오.
이는 InnoDB 테이블에 대해 추가적인 에러 체크를 활성화합니다.
MySQL 9.5의 기본 SQL 모드에는 다음 모드가 포함됩니다:
ONLY_FULL_GROUP_BY,
STRICT_TRANS_TABLES,
NO_ZERO_IN_DATE,
NO_ZERO_DATE,
ERROR_FOR_DIVISION_BY_ZERO,
그리고 NO_ENGINE_SUBSTITUTION 입니다.
서버 시작 시 SQL 모드를 설정하려면,
커맨드 라인에서 --sql-mode="modes"
옵션을 사용하거나, my.cnf(유닉스 운영체제) 또는
my.ini(Windows)와 같은 옵션 파일에서
sql-mode="modes"을 사용하십시오.
modes 는 쉼표로 구분된 여러 모드의 목록입니다.
SQL 모드를 명시적으로 비우려면, 커맨드 라인에서
--sql-mode=""을 사용하거나,
옵션 파일에서 sql-mode=""로
빈 문자열로 설정하십시오.
참고
MySQL 설치 프로그램은 설치 과정에서 SQL 모드를 설정하도록 구성되어 있을 수 있습니다.
SQL 모드가 기본값 또는 예상과 다르다면, 서버가 시작 시 읽는 옵션 파일에 설정이 있는지 확인하십시오.
런타임에 SQL 모드를 변경하려면,
SET
문을 사용하여 글로벌 또는 세션
sql_mode 시스템 변수를 설정하십시오:
1SET GLOBAL sql_mode = 'modes'; 2SET SESSION sql_mode = 'modes';
GLOBAL 변수를 설정하려면
SYSTEM_VARIABLES_ADMIN 권한
(또는 더 이상 사용되지 않는(deprecated) SUPER
권한)이 필요하며, 이후에 연결하는 모든 클라이언트의 동작에 영향을 줍니다.
SESSION 변수를 설정하면 현재 클라이언트에만 영향을 줍니다.
각 클라이언트는 언제든지 자신의 세션
sql_mode 값을 변경할 수 있습니다.
현재 글로벌 또는 세션
sql_mode 설정을 확인하려면,
그 값을 select 하십시오:
1SELECT @@GLOBAL.sql_mode; 2SELECT @@SESSION.sql_mode;
주의
SQL 모드와 user-defined partitioning.
partitioned 테이블을 생성하고 데이터를 insert한 후에 서버 SQL 모드를 변경하면 해당 테이블의 동작이 크게 변경될 수 있으며, 데이터 손실이나 손상이 발생할 수 있습니다. user-defined partitioning을 사용하는 테이블을 생성한 이후에는 결코 SQL 모드를 변경하지 말 것을 강력히 권장합니다.
partitioned 테이블을 복제(replication)할 때, 소스와 레플리카의 SQL 모드가 서로 다르면 문제를 일으킬 수 있습니다. 최상의 결과를 얻으려면 소스와 레플리카에서 항상 같은 서버 SQL 모드를 사용해야 합니다.
자세한 내용은 Section 26.6, “Restrictions and Limitations on Partitioning”을 참조하십시오.
가장 중요한 sql_mode
값은 아마도 다음과 같습니다:
이 모드는 구문과 동작을 변경하여 표준 SQL에 보다 가깝게 맞춥니다. 이 모드는 이 섹션 끝에 나열된 특수 combination modes 중 하나입니다.
값이 트랜잭션 테이블에 주어진 그대로 insert될 수 없을 경우, 해당 문을 중단합니다. 논트랜잭션 테이블의 경우, single-row 문이나 multiple-row 문의 첫 번째 row에서 이러한 값이 발생하면 문을 중단합니다. 자세한 내용은 이 섹션의 뒷부분에서 설명합니다.
MySQL이 “전통적인(traditional)” SQL 데이터베이스 시스템처럼 동작하도록 합니다. 이 모드를 간단히 설명하면, 컬럼에 잘못된 값을 insert할 때 “warning 대신 에러를 발생시키는 것”입니다. 이 모드는 이 섹션 끝에 나열된 특수 combination modes 중 하나입니다.
참고
TRADITIONAL 모드가
활성화되어 있을 때, INSERT 또는
UPDATE는
에러가 발생하는 즉시 중단됩니다.
논트랜잭션 스토리지 엔진을 사용하는 경우,
에러 이전에 수행된 데이터 변경이 롤백되지 않을 수 있으므로
“부분적으로만 수행된(partially done)” update가 발생할 수 있어서
원치 않는 결과일 수 있습니다.
이 매뉴얼에서 “strict mode”라고 할 때는,
STRICT_TRANS_TABLES 또는
STRICT_ALL_TABLES 중 하나 혹은 둘 다가
활성화된 모드를 의미합니다.
다음 목록은 지원되는 모든 SQL 모드를 설명합니다:
date에 대한 전체 검사를 수행하지 않습니다.
month가 1에서 12, day가 1에서 31 범위에 있는지만 검사합니다.
이는 웹 애플리케이션에서
year, month, day를 세 개의 서로 다른 필드로 입력받아
사용자가 입력한 값을 date 검증 없이 그대로 저장하고자 할 때 유용할 수 있습니다.
이 모드는
DATE 및
DATETIME 컬럼에 적용됩니다.
TIMESTAMP 컬럼에는 적용되지 않으며,
TIMESTAMP 컬럼은 항상 유효한 date가 필요합니다.
ALLOW_INVALID_DATES가
비활성화된 경우, 서버는 month와 day 값이
단순히 1에서 12, 1에서 31 범위에 있는지 뿐만 아니라
법적으로 유효한 값이어야 합니다.
strict 모드가 비활성화된 경우,
'2004-04-31' 같은 invalid date는
'0000-00-00'으로 변환되고 warning이 생성됩니다.
strict 모드가 활성화된 경우,
invalid date는 에러를 생성합니다.
이러한 date를 허용하려면
ALLOW_INVALID_DATES를 활성화하십시오.
"를 문자열 quote 문자 대신
(````` quote 문자처럼) 식별자 quote 문자로 처리합니다.
이 모드가 활성화된 상태에서도
식별자를 quote하기 위해
[`ANSI_QUOTES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ansi_quotes)가
활성화된 상태에서는
double quotation mark를 리터럴 문자열을 quote하는 데 사용할 수 없는데,
이들은 식별자로 해석되기 때문입니다.
- [`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)
모드는 0으로 나누는 연산( [`MOD(N,0)`](https://dev.mysql.com/doc/refman/9.5/en/mathematical-functions.html#function_mod) 포함)의 처리 방식에 영향을 줍니다.
데이터 변경 연산
([`INSERT`](https://dev.mysql.com/doc/refman/9.5/en/insert.html "15.2.7 INSERT Statement"),
[`UPDATE`](https://dev.mysql.com/doc/refman/9.5/en/update.html "15.2.17 UPDATE Statement"))의 경우,
그 효과는 strict SQL 모드가 활성화되었는지 여부에 따라서도 달라집니다.
- 이 모드가 비활성화된 경우,
0으로 나누면 `NULL`이 insert되고 warning은 발생하지 않습니다.
- 이 모드가 활성화된 경우,
0으로 나누면 `NULL`이 insert되고 warning이 발생합니다.
- 이 모드와 strict 모드가 모두 활성화된 경우,
`IGNORE`가 함께 지정되지 않는 한
0으로 나누면 에러가 발생합니다.
`INSERT IGNORE` 및
`UPDATE IGNORE`의 경우,
0으로 나누면 `NULL`이 insert되고 warning이 발생합니다.
[`SELECT`](https://dev.mysql.com/doc/refman/9.5/en/select.html "15.2.13 SELECT Statement")에 대해서는,
0으로 나누면 `NULL`을 반환합니다.
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)를
활성화하면 strict 모드 활성화 여부에 관계없이 warning도 발생합니다.
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)는
deprecated되었습니다.
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)는
strict 모드의 일부가 아니지만,
strict 모드와 함께 사용해야 하며 기본적으로 활성화되어 있습니다.
strict 모드는 활성화하지 않고
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)만 활성화했거나,
그 반대인 경우 warning이 발생합니다.
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero)가
deprecated되었으므로,
향후 MySQL 릴리스에서 별도의 모드 이름으로서는 제거되고,
그 효과는 strict SQL 모드의 효과에 포함될 것으로 예상해야 합니다.
- [`HIGH_NOT_PRECEDENCE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_high_not_precedence)
[`NOT`](https://dev.mysql.com/doc/refman/9.5/en/logical-operators.html#operator_not)
연산자의 우선순위는
`NOT a BETWEEN b AND c` 같은 표현식이
`NOT (a BETWEEN b AND c)`로 파싱되도록 정해져 있습니다.
이전 MySQL의 일부 오래된 버전에서는
이 표현식이 `(NOT a) BETWEEN b AND c`로 파싱되었습니다.
이전의 더 높은 우선순위 동작은
[`HIGH_NOT_PRECEDENCE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_high_not_precedence) SQL 모드를
활성화하여 얻을 수 있습니다.
```sql
mysql> SET sql_mode = '';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 0
mysql> SET sql_mode = 'HIGH_NOT_PRECEDENCE';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 1
```
- [`IGNORE_SPACE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ignore_space)
함수 이름과 `(` 문자 사이에 공백을 허용합니다.
이로 인해 빌트인 함수 이름이 예약어처럼 취급됩니다.
그 결과, 함수 이름과 동일한 식별자는
[Section 11.2, “Schema Object Names”](https://dev.mysql.com/doc/refman/9.5/en/identifiers.html "11.2 Schema Object Names")에 설명된 대로
quote해야 합니다.
예를 들어,
[`COUNT()`](https://dev.mysql.com/doc/refman/9.5/en/aggregate-functions.html#function_count) 함수가 있기 때문에,
다음 문에서 `count`를 테이블 이름으로 사용하면
에러가 발생합니다:
```sql
mysql> CREATE TABLE count (i INT);
ERROR 1064 (42000): You have an error in your SQL syntax
```
테이블 이름은 다음과 같이 quote해야 합니다:
```sql
mysql> CREATE TABLE `count` (i INT);
Query OK, 0 rows affected (0.00 sec)
```
[`IGNORE_SPACE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ignore_space) SQL 모드는
빌트인 함수에 적용되며,
loadable 함수나 저장 함수에는 적용되지 않습니다.
[`IGNORE_SPACE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ignore_space) 활성 여부와 관계없이,
loadable 함수나 저장 함수 이름 뒤에는
항상 공백을 둘 수 있습니다.
[`IGNORE_SPACE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ignore_space)에 대한 추가 논의는
[Section 11.2.5, “Function Name Parsing and Resolution”](https://dev.mysql.com/doc/refman/9.5/en/function-resolution.html "11.2.5 Function Name Parsing and Resolution")을 참조하십시오.
- [`NO_AUTO_VALUE_ON_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_auto_value_on_zero)
[`NO_AUTO_VALUE_ON_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_auto_value_on_zero)는
`AUTO_INCREMENT` 컬럼 처리에 영향을 줍니다.
일반적으로 컬럼에 `NULL` 또는
`0`을 insert하여 다음 시퀀스 번호를 생성합니다.
[`NO_AUTO_VALUE_ON_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_auto_value_on_zero)는
`0`에 대해 이러한 동작을 억제하여,
오직 `NULL`만이 다음 시퀀스 번호를
생성하도록 합니다.
이 모드는 테이블의 `AUTO_INCREMENT`
컬럼에 `0`이 저장되어 있을 때 유용할 수 있습니다.
(참고로 `0` 저장은 권장되는 관행이 아닙니다.)
예를 들어, 테이블을 [**mysqldump**](https://dev.mysql.com/doc/refman/9.5/en/mysqldump.html "6.5.4 mysqldump — A Database Backup Program")로 dump한 다음 reload하면,
MySQL은 일반적으로 `0` 값을 만날 때마다
새로운 시퀀스 번호를 생성하여,
dump되었던 테이블과는 다른 내용의 테이블을 만들게 됩니다.
dump 파일을 reload하기 전에
[`NO_AUTO_VALUE_ON_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_auto_value_on_zero)를 활성화하면
이 문제를 해결할 수 있습니다.
이러한 이유로 [**mysqldump**](https://dev.mysql.com/doc/refman/9.5/en/mysqldump.html "6.5.4 mysqldump — A Database Backup Program")는
output에
[`NO_AUTO_VALUE_ON_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_auto_value_on_zero)를
활성화하는 문을 자동으로 포함합니다.
- [`NO_BACKSLASH_ESCAPES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_backslash_escapes)
이 모드를 활성화하면
문자열과 식별자 내에서 backslash 문자(`\`)를
이스케이프 문자로 사용하는 것이 비활성화됩니다.
이 모드가 활성화된 상태에서는
backslash가 다른 문자와 마찬가지의 일반 문자로 취급되며,
[`LIKE`](https://dev.mysql.com/doc/refman/9.5/en/string-comparison-functions.html#operator_like) 표현식에 대한
기본 이스케이프 시퀀스는 이스케이프 문자를 사용하지 않도록 변경됩니다.
- [`NO_DIR_IN_CREATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_dir_in_create)
테이블을 생성할 때,
모든 `INDEX DIRECTORY` 및
`DATA DIRECTORY` 지시어를 무시합니다.
이 옵션은 레플리카 서버에서 유용합니다.
- [`NO_ENGINE_SUBSTITUTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_engine_substitution)
[`CREATE TABLE`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement")나
[`ALTER TABLE`](https://dev.mysql.com/doc/refman/9.5/en/alter-table.html "15.1.11 ALTER TABLE Statement")과 같은 문이
비활성화되었거나 컴파일되어 있지 않은 스토리지 엔진을 지정할 때,
기본 스토리지 엔진으로 자동 대체하는 동작을 제어합니다.
기본적으로
[`NO_ENGINE_SUBSTITUTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_engine_substitution)는
활성화되어 있습니다.
스토리지 엔진은 런타임에 플러그인할 수 있으므로,
사용할 수 없는 엔진은 동일한 방식으로 처리됩니다:
[`NO_ENGINE_SUBSTITUTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_engine_substitution)가
비활성화된 상태에서는,
[`CREATE TABLE`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement)의 경우
원하는 엔진을 사용할 수 없으면 기본 엔진이 사용되고 warning이 발생합니다.
[`ALTER TABLE`](https://dev.mysql.com/doc/refman/9.5/en/alter-table.html "15.1.11 ALTER TABLE Statement")의 경우
warning이 발생하고 테이블은 변경되지 않습니다.
[`NO_ENGINE_SUBSTITUTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_engine_substitution)가
활성화된 상태에서는,
원하는 엔진을 사용할 수 없으면 에러가 발생하고
테이블이 생성되거나 변경되지 않습니다.
- [`NO_UNSIGNED_SUBTRACTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_unsigned_subtraction)
정수 값 간의 뺄셈에서 한 쪽이 `UNSIGNED` 타입이면,
기본적으로 결과는 unsigned입니다.
만약 결과가 음수가 되었을 경우, 에러가 발생합니다:
```sql
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
```
[`NO_UNSIGNED_SUBTRACTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_unsigned_subtraction)
SQL 모드가 활성화된 경우, 결과는 음수가 됩니다:
```sql
mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 AS UNSIGNED) - 1 |
+-------------------------+
| -1 |
+-------------------------+
```
이러한 연산의 결과를 `UNSIGNED` 정수 컬럼을
update하는 데 사용하는 경우,
결과는 컬럼 타입의 최대값으로 잘리거나,
[`NO_UNSIGNED_SUBTRACTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_unsigned_subtraction)가
활성화된 경우 0으로 잘립니다.
strict SQL 모드가 활성화된 경우,
에러가 발생하고 컬럼은 변경되지 않습니다.
[`NO_UNSIGNED_SUBTRACTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_unsigned_subtraction)가
활성화된 경우,
뺄셈 결과는 _어떠한 피연산자가 unsigned이더라도_
signed입니다.
예를 들어, 테이블 `t1`의 컬럼
`c2` 타입을 테이블 `t2`의
컬럼 `c2` 타입과 비교하십시오:
```sql
mysql> SET sql_mode='';
mysql> CREATE TABLE test (c1 BIGINT UNSIGNED NOT NULL);
mysql> CREATE TABLE t1 SELECT c1 - 1 AS c2 FROM test;
mysql> DESCRIBE t1;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| c2 | bigint(21) unsigned | NO | | 0 | |
+-------+---------------------+------+-----+---------+-------+
mysql> SET sql_mode='NO_UNSIGNED_SUBTRACTION';
mysql> CREATE TABLE t2 SELECT c1 - 1 AS c2 FROM test;
mysql> DESCRIBE t2;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| c2 | bigint(21) | NO | | 0 | |
+-------+------------+------+-----+---------+-------+
```
이는 `BIGINT UNSIGNED`가
모든 컨텍스트에서 100% 사용 가능하지 않다는 것을 의미합니다.
[Section 14.10, “Cast Functions and Operators”](https://dev.mysql.com/doc/refman/9.5/en/cast-functions.html "14.10 Cast Functions and Operators")를 참조하십시오.
- [`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date)
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date) 모드는
서버가 `'0000-00-00'`를
유효한 date로 허용할지 여부에 영향을 줍니다.
그 효과는 strict SQL 모드가 활성화되었는지 여부에 따라서도 달라집니다.
- 이 모드가 비활성화된 경우,
`'0000-00-00'`가 허용되며
insert 시 warning이 발생하지 않습니다.
- 이 모드가 활성화된 경우,
`'0000-00-00'`가 허용되며
insert 시 warning이 발생합니다.
- 이 모드와 strict 모드가 모두 활성화된 경우,
`'0000-00-00'`는 허용되지 않으며
insert 시 에러가 발생합니다.
단, `IGNORE`가 함께 지정된 경우는 예외입니다.
`INSERT IGNORE` 및
`UPDATE IGNORE`의 경우,
`'0000-00-00'`가 허용되며
insert 시 warning이 발생합니다.
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date)는
deprecated되었습니다.
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date)는
strict 모드의 일부가 아니지만,
strict 모드와 함께 사용해야 하며 기본적으로 활성화되어 있습니다.
strict 모드는 활성화하지 않고
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date)만 활성화했거나,
그 반대인 경우 warning이 발생합니다.
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date)가
deprecated되었으므로,
향후 MySQL 릴리스에서 별도의 모드 이름으로서는 제거되고,
그 효과는 strict SQL 모드의 효과에 포함될 것으로 예상해야 합니다.
- [`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date)
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date) 모드는
year 부분은 0이 아니지만 month나 day 부분이 0인 date를
서버가 허용할지 여부에 영향을 줍니다.
(이 모드는 `'2010-00-01'` 또는
`'2010-01-00'` 같은 date에 영향을 주지만,
`'0000-00-00'`에는 영향을 주지 않습니다.
서버가 `'0000-00-00'`를 허용할지 제어하려면
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date) 모드를 사용하십시오.)
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date)의 효과는
strict SQL 모드가 활성화되었는지 여부에 따라서도 달라집니다.
- 이 모드가 비활성화된 경우,
zero 부분이 있는 date는 허용되며
insert 시 warning이 발생하지 않습니다.
- 이 모드가 활성화된 경우,
zero 부분이 있는 date는
`'0000-00-00'`로 insert되며
warning이 발생합니다.
- 이 모드와 strict 모드가 모두 활성화된 경우,
zero 부분이 있는 date는 허용되지 않으며
insert 시 에러가 발생합니다.
단, `IGNORE`가 함께 지정된 경우는 예외입니다.
`INSERT IGNORE` 및
`UPDATE IGNORE`의 경우,
zero 부분이 있는 date는
`'0000-00-00'`로 insert되며
warning이 발생합니다.
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date)는
deprecated되었습니다.
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date)는
strict 모드의 일부가 아니지만,
strict 모드와 함께 사용해야 하며 기본적으로 활성화되어 있습니다.
strict 모드는 활성화하지 않고
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date)만 활성화했거나,
그 반대인 경우 warning이 발생합니다.
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date)가
deprecated되었으므로,
향후 MySQL 릴리스에서 별도의 모드 이름으로서는 제거되고,
그 효과는 strict SQL 모드의 효과에 포함될 것으로 예상해야 합니다.
- [`ONLY_FULL_GROUP_BY`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_only_full_group_by)
select 리스트, `HAVING` 조건 또는
`ORDER BY` 리스트가
`GROUP BY` 절에 명시되지 않았거나
`GROUP BY` 컬럼에 functionally dependent
(즉, `GROUP BY` 컬럼으로 유일하게 결정되는)하지 않은
nonaggregated 컬럼을 참조하는 쿼리를 거부합니다.
표준 SQL에 대한 MySQL 확장은
`HAVING` 절에서 select 리스트에 있는 alias 표현을 참조할 수 있도록 허용합니다.
`HAVING` 절은
[`ONLY_FULL_GROUP_BY`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_only_full_group_by)의
활성 여부와 관계없이 alias를 참조할 수 있습니다.
추가적인 논의와 예시는
[Section 14.19.3, “MySQL Handling of GROUP BY”](https://dev.mysql.com/doc/refman/9.5/en/group-by-handling.html "14.19.3 MySQL Handling of GROUP BY")를 참조하십시오.
- [`PAD_CHAR_TO_FULL_LENGTH`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_pad_char_to_full_length)
기본적으로, 조회 시
[`CHAR`](https://dev.mysql.com/doc/refman/9.5/en/char.html "13.3.2 The CHAR and VARCHAR Types") 컬럼 값의
후행 공백은 잘려나갑니다.
[`PAD_CHAR_TO_FULL_LENGTH`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_pad_char_to_full_length)가
활성화된 경우,
이 trimming은 발생하지 않고
조회된 [`CHAR`](https://dev.mysql.com/doc/refman/9.5/en/char.html "13.3.2 The CHAR and VARCHAR Types") 값은
그들의 전체 길이로 padding됩니다.
이 모드는
[`VARCHAR`](https://dev.mysql.com/doc/refman/9.5/en/char.html "13.3.2 The CHAR and VARCHAR Types") 컬럼에는 적용되지 않으며,
`VARCHAR` 컬럼의 후행 공백은 조회 시 유지됩니다.
**참고**
[`PAD_CHAR_TO_FULL_LENGTH`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_pad_char_to_full_length)는
deprecated되었습니다.
향후 MySQL 버전에서 제거될 것으로 예상하십시오.
```sql
mysql> CREATE TABLE t1 (c1 CHAR(10));
Query OK, 0 rows affected (0.37 sec)
mysql> INSERT INTO t1 (c1) VALUES('xy');
Query OK, 1 row affected (0.01 sec)
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT c1, CHAR_LENGTH(c1) FROM t1;
+------+-----------------+
| c1 | CHAR_LENGTH(c1) |
+------+-----------------+
| xy | 2 |
+------+-----------------+
1 row in set (0.00 sec)
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT c1, CHAR_LENGTH(c1) FROM t1;
+------------+-----------------+
| c1 | CHAR_LENGTH(c1) |
+------------+-----------------+
| xy | 10 |
+------------+-----------------+
1 row in set (0.00 sec)
```
- [`PIPES_AS_CONCAT`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_pipes_as_concat)
[`||`](https://dev.mysql.com/doc/refman/9.5/en/logical-operators.html#operator_or)를
[`OR`](https://dev.mysql.com/doc/refman/9.5/en/logical-operators.html#operator_or)의 synonym이 아니라,
[`CONCAT()`](https://dev.mysql.com/doc/refman/9.5/en/string-functions.html#function_concat)와 동일한
문자열 연결 연산자로 처리합니다.
- [`REAL_AS_FLOAT`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_real_as_float)
[`REAL`](https://dev.mysql.com/doc/refman/9.5/en/floating-point-types.html "13.1.4 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE")을
[`FLOAT`](https://dev.mysql.com/doc/refman/9.5/en/floating-point-types.html "13.1.4 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE")의 synonym으로 취급합니다.
기본적으로 MySQL은
[`REAL`](https://dev.mysql.com/doc/refman/9.5/en/floating-point-types.html "13.1.4 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE")을
[`DOUBLE`](https://dev.mysql.com/doc/refman/9.5/en/floating-point-types.html "13.1.4 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE")의 synonym으로 취급합니다.
- [`STRICT_ALL_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_all_tables)
모든 스토리지 엔진에 대해 strict SQL 모드를 활성화합니다.
invalid 데이터 값은 거부됩니다.
자세한 내용은
[Strict SQL Mode](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sql-mode-strict "Strict SQL Mode")를 참조하십시오.
- [`STRICT_TRANS_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_trans_tables)
트랜잭션 스토리지 엔진에 대해 strict SQL 모드를 활성화하고,
가능한 경우 논트랜잭션 스토리지 엔진에 대해서도 활성화합니다.
자세한 내용은
[Strict SQL Mode](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sql-mode-strict "Strict SQL Mode")를 참조하십시오.
- [`TIME_TRUNCATE_FRACTIONAL`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_time_truncate_fractional)
fractional seconds 부분을 가진
[`TIME`](https://dev.mysql.com/doc/refman/9.5/en/time.html "13.2.3 The TIME Type"),
[`DATE`](https://dev.mysql.com/doc/refman/9.5/en/datetime.html "13.2.2 The DATE, DATETIME, and TIMESTAMP Types"),
[`TIMESTAMP`](https://dev.mysql.com/doc/refman/9.5/en/datetime.html "13.2.2 The DATE, DATETIME, and TIMESTAMP Types") 값을
같은 타입이지만 fractional digit 수가 더 적은 컬럼에 insert할 때,
rounding 또는 truncation 중 무엇이 발생할지 제어합니다.
기본 동작은 rounding을 사용하는 것입니다.
이 모드가 활성화된 경우, 그 대신 truncation이 발생합니다.
다음 문 시퀀스는 차이를 보여 줍니다:
```sql
CREATE TABLE t (id INT, tval TIME(1));
SET sql_mode='';
INSERT INTO t (id, tval) VALUES(1, 1.55);
SET sql_mode='TIME_TRUNCATE_FRACTIONAL';
INSERT INTO t (id, tval) VALUES(2, 1.55);
```
결과 테이블 내용은 다음과 같으며,
첫 번째 값에는 rounding이, 두 번째 값에는 truncation이 적용되었습니다:
```sql
mysql> SELECT id, tval FROM t ORDER BY id;
+------+------------+
| id | tval |
+------+------------+
| 1 | 00:00:01.6 |
| 2 | 00:00:01.5 |
+------+------------+
```
또한
[Section 13.2.6, “Fractional Seconds in Time Values”](https://dev.mysql.com/doc/refman/9.5/en/fractional-seconds.html "13.2.6 Fractional Seconds in Time Values")도 참조하십시오.
#### Combination SQL Modes
다음 특수 모드는 앞선 목록의 모드 값 조합에 대한
shorthand로 제공됩니다.
- [`ANSI`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ansi)
다음과 동등합니다:
[`REAL_AS_FLOAT`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_real_as_float),
[`PIPES_AS_CONCAT`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_pipes_as_concat),
[`ANSI_QUOTES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ansi_quotes),
[`IGNORE_SPACE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ignore_space),
[`ONLY_FULL_GROUP_BY`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_only_full_group_by).
[`ANSI`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ansi) 모드는 또한,
outer reference에 대해 resolve된 outer 쿼리에서
집계할 수 없는 set 함수 _`S`_ 의 outer reference
`S(outer_ref)`를 포함하는 쿼리에 대해
에러를 반환하도록 서버에 지시합니다.
해당 쿼리는 다음과 같습니다:
```sql
SELECT * FROM t1 WHERE t1.a IN (SELECT MAX(t1.b) FROM t2 WHERE ...);
```
여기서 [`MAX(t1.b)`](https://dev.mysql.com/doc/refman/9.5/en/aggregate-functions.html#function_max)는
outer 쿼리의 `WHERE` 절에 나타나므로,
outer 쿼리에서 집계될 수 없습니다.
표준 SQL은 이 상황에서 에러를 요구합니다.
[`ANSI`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_ansi) 모드가 활성화되어 있지 않으면,
서버는 이러한 쿼리의
`S(outer_ref)`를
`S(const)`를 해석하는 방식과 동일하게 해석합니다.
[Section 1.7, “MySQL Standards Compliance”](https://dev.mysql.com/doc/refman/9.5/en/compatibility.html "1.7 MySQL Standards Compliance")를 참조하십시오.
- [`TRADITIONAL`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_traditional)
[`TRADITIONAL`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_traditional)은
다음과 동등합니다:
[`STRICT_TRANS_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_trans_tables),
[`STRICT_ALL_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_all_tables),
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date),
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date),
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero),
[`NO_ENGINE_SUBSTITUTION`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_engine_substitution).
#### Strict SQL Mode
strict 모드는
[`INSERT`](https://dev.mysql.com/doc/refman/9.5/en/insert.html "15.2.7 INSERT Statement")나
[`UPDATE`](https://dev.mysql.com/doc/refman/9.5/en/update.html "15.2.17 UPDATE Statement") 같은
데이터 변경 문에서 invalid하거나 누락된 값을
MySQL이 어떻게 처리할지를 제어합니다.
값이 invalid한 이유는 여러 가지가 있을 수 있습니다.
예를 들어, 컬럼에 대해 잘못된 데이터 타입을 가졌거나
범위를 벗어난 값일 수 있습니다.
새 row를 insert할 때,
명시적인 `DEFAULT` 절이 없는
non-`NULL` 컬럼에 대해 값이 주어지지 않은 경우
그 값은 누락된 값입니다.
(`NULL` 컬럼의 경우,
값이 누락되면 `NULL`이 insert됩니다.)
strict 모드는
[`CREATE TABLE`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement)와 같은
DDL 문에도 영향을 줍니다.
strict 모드가 아닐 때는,
MySQL은 invalid하거나 누락된 값에 대해 보정(adjusted) 값을 insert하고
warning을 생성합니다
([Section 15.7.7.43, “SHOW WARNINGS Statement”](https://dev.mysql.com/doc/refman/9.5/en/show-warnings.html "15.7.7.43 SHOW WARNINGS Statement") 참조).
strict 모드에서도,
[`INSERT IGNORE`](https://dev.mysql.com/doc/refman/9.5/en/insert.html "15.2.7 INSERT Statement") 또는
[`UPDATE IGNORE`](https://dev.mysql.com/doc/refman/9.5/en/update.html "15.2.17 UPDATE Statement")를 사용하면
이러한 동작을 유도할 수 있습니다.
데이터를 변경하지 않는
[`SELECT`](https://dev.mysql.com/doc/refman/9.5/en/select.html "15.2.13 SELECT Statement") 같은 문의 경우,
strict 모드에서는 invalid 값에 대해 warning이 생성되지만
에러는 발생하지 않습니다.
strict 모드는 최대 key 길이를 초과하는 key를 생성하려는 시도에 대해
에러를 발생시킵니다.
strict 모드가 활성화되어 있지 않으면,
warning이 발생하고 key는 최대 key 길이로 잘립니다.
strict 모드는 foreign key 제약 조건을 확인할지 여부에는 영향을 주지 않습니다.
이를 위해서는
[`foreign_key_checks`](https://dev.mysql.com/doc/refman/9.5/en/server-system-variables.html#sysvar_foreign_key_checks)를
사용할 수 있습니다.
([Section 7.1.8, “Server System Variables”](https://dev.mysql.com/doc/refman/9.5/en/server-system-variables.html "7.1.8 Server System Variables")를 참조하십시오.)
다음 중 하나가 활성화되어 있으면 strict SQL 모드가 적용됩니다:
[`STRICT_ALL_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_all_tables) 또는
[`STRICT_TRANS_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_trans_tables).
두 모드의 효과는 약간 다릅니다:
- 트랜잭션 테이블의 경우,
데이터 변경 문에서 invalid하거나 누락된 값이 발생하면
[`STRICT_ALL_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_all_tables) 또는
[`STRICT_TRANS_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_trans_tables) 중
어느 하나가 활성화되었을 때 에러가 발생합니다.
문은 중단되고 롤백됩니다.
- 논트랜잭션 테이블의 경우,
첫 번째로 insert 또는 update되는 row에서
잘못된 값이 발생하면, 두 모드 모두 동일한 동작을 보입니다:
문이 중단되고 테이블은 변경되지 않습니다.
문이 여러 row를 insert 또는 변경하는데,
잘못된 값이 두 번째 또는 그 이후의 row에서 발생하는 경우,
어느 strict 모드가 활성화되어 있는지에 따라 결과가 달라집니다:
- [`STRICT_ALL_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_all_tables)의 경우,
MySQL은 에러를 반환하고 나머지 row를 무시합니다.
그러나, 앞서 insert되거나 update된 row는 이미 반영되었으므로
결과는 partial update입니다.
이를 피하려면, 테이블을 변경 없이 abort할 수 있도록
single-row 문을 사용하십시오.
- [`STRICT_TRANS_TABLES`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_strict_trans_tables)의 경우,
MySQL은 invalid 값을 해당 컬럼에 가능한 가장 가까운 유효한 값으로 변환하여
보정된 값을 insert합니다.
값이 누락된 경우,
MySQL은 컬럼 데이터 타입에 대한 implicit default 값을 insert합니다.
두 경우 모두 MySQL은 에러 대신 warning을 생성하고
문 처리를 계속합니다.
implicit default에 대해서는
[Section 13.6, “Data Type Default Values”](https://dev.mysql.com/doc/refman/9.5/en/data-type-defaults.html "13.6 Data Type Default Values")를 참조하십시오.
strict 모드는 다음과 같이
0으로 나누기, 0 date, date의 0 값 처리에 영향을 줍니다:
- strict 모드는
0으로 나누기( [`MOD(N,0)`](https://dev.mysql.com/doc/refman/9.5/en/mathematical-functions.html#function_mod) 포함) 처리에 영향을 줍니다:
데이터 변경 연산
([`INSERT`](https://dev.mysql.com/doc/refman/9.5/en/insert.html "15.2.7 INSERT Statement"),
[`UPDATE`](https://dev.mysql.com/doc/refman/9.5/en/update.html "15.2.17 UPDATE Statement"))의 경우:
- strict 모드가 비활성화된 경우,
0으로 나누면 `NULL`이 insert되고 warning은 발생하지 않습니다.
- strict 모드가 활성화된 경우,
`IGNORE`가 함께 지정되지 않는 한
0으로 나누면 에러가 발생합니다.
`INSERT IGNORE` 및
`UPDATE IGNORE`의 경우,
0으로 나누면 `NULL`이 insert되고 warning이 발생합니다.
[`SELECT`](https://dev.mysql.com/doc/refman/9.5/en/select.html "15.2.13 SELECT Statement")에 대해서는,
0으로 나누면 `NULL`을 반환합니다.
strict 모드를 활성화하면 warning도 함께 발생합니다.
- strict 모드는 서버가
`'0000-00-00'`를
유효한 date로 허용할지 여부에 영향을 줍니다:
- strict 모드가 비활성화된 경우,
`'0000-00-00'`는 허용되며
insert 시 warning이 발생하지 않습니다.
- strict 모드가 활성화된 경우,
`'0000-00-00'`는 허용되지 않으며
insert 시 에러가 발생합니다.
단, `IGNORE`가 함께 지정된 경우는 예외입니다.
`INSERT IGNORE` 및
`UPDATE IGNORE`의 경우,
`'0000-00-00'`는 허용되며
insert 시 warning이 발생합니다.
- strict 모드는 year 부분은 0이 아니지만
month나 day 부분이 0인 date
(`'2010-00-01'` 또는
`'2010-01-00'` 같은 date)을
서버가 허용할지 여부에 영향을 줍니다:
- strict 모드가 비활성화된 경우,
zero 부분이 있는 date는 허용되며
insert 시 warning이 발생하지 않습니다.
- strict 모드가 활성화된 경우,
zero 부분이 있는 date는 허용되지 않으며
insert 시 에러가 발생합니다.
단, `IGNORE`가 함께 지정된 경우는 예외입니다.
`INSERT IGNORE` 및
`UPDATE IGNORE`의 경우,
zero 부분이 있는 date는
`'0000-00-00'`로 insert되며
(`IGNORE`와 함께라면 유효한 것으로 간주됨)
warning이 발생합니다.
`IGNORE`와 관련된 strict 모드에 대한 자세한 내용은
[Comparison of the IGNORE Keyword and Strict SQL Mode](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#ignore-strict-comparison "Comparison of the IGNORE Keyword and Strict SQL Mode")를
참조하십시오.
strict 모드는
[`ERROR_FOR_DIVISION_BY_ZERO`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_error_for_division_by_zero),
[`NO_ZERO_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_date),
[`NO_ZERO_IN_DATE`](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#sqlmode_no_zero_in_date) 모드와 함께
0으로 나누기, 0 date, date의 0 값 처리를 제어합니다.
#### Comparison of the IGNORE Keyword and Strict SQL Mode
이 섹션에서는
에러를 warning으로 낮추는(downgrade) `IGNORE` 키워드와
warning을 에러로 올리는(upgrade) strict SQL 모드가
문 실행에 미치는 효과를 비교합니다.
이들은 어떤 문에 영향을 미치는지,
어떤 에러에 적용되는지를 설명합니다.
다음 테이블은
문의 기본 동작이 에러를 생성하는 경우와
warning을 생성하는 경우에 대한
문 동작을 요약 비교합니다.
문의 기본 동작이 에러인 예로는,
`NOT NULL` 컬럼에 `NULL`을 insert하는 경우가 있습니다.
문의 기본 동작이 warning인 예로는,
정수 컬럼에 문자열
`'abc'`를 insert하는 것처럼
잘못된 데이터 타입 값을 컬럼에 insert하는 경우가 있습니다.
| Operational Mode | When Statement Default is Error | When Statement Default is Warning |
| --- | --- | --- |
| Without `IGNORE` or strict SQL mode | Error | Warning |
| With `IGNORE` | Warning | Warning (same as without `IGNORE` or strict SQL mode) |
| With strict SQL mode | Error (same as without `IGNORE` or strict SQL mode) | Error |
| With `IGNORE` and strict SQL mode | Warning | Warning |
이 테이블에서 얻을 수 있는 결론 중 하나는,
`IGNORE` 키워드와 strict SQL 모드가 모두
적용되는 경우, `IGNORE`가 우선한다는 것입니다.
즉, `IGNORE`와 strict SQL 모드는
에러 처리에 대해 서로 반대되는 효과를 갖는다고 볼 수 있지만,
함께 사용할 때 서로 상쇄되지는 않습니다.
- [The Effect of IGNORE on Statement Execution](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#ignore-effect-on-execution "The Effect of IGNORE on Statement Execution")
- [The Effect of Strict SQL Mode on Statement Execution](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html#strict-sql-mode-effect-on-execution "The Effect of Strict SQL Mode on Statement Execution")
##### The Effect of IGNORE on Statement Execution
MySQL의 여러 문은 선택적인
`IGNORE` 키워드를 지원합니다.
이 키워드는 특정 유형의 에러를
warning으로 낮추도록 서버에 지시합니다.
multiple-row 문에서
에러를 warning으로 낮추면
해당 row를 처리할 수 있게 될 수 있습니다.
그렇지 않으면 `IGNORE`는
문이 abort되는 대신 다음 row로 건너뛰게 합니다.
(무시할 수 없는 nonignorable 에러의 경우,
`IGNORE` 키워드와 관계없이 에러가 발생합니다.)
예: 테이블 `t`에 고유한 값을 가진
프라이머리 키 컬럼 `i`가 있는 경우,
여러 row에 대해 같은 `i` 값을 insert하려고 하면
보통 duplicate-key 에러가 발생합니다:
```sql
mysql> CREATE TABLE t (i INT NOT NULL PRIMARY KEY);
mysql> INSERT INTO t (i) VALUES(1),(1);
ERROR 1062 (23000): Duplicate entry '1' for key 't.PRIMARY'
```
`IGNORE`를 사용하면,
duplicate key를 포함하는 row는 여전히 insert되지 않지만,
에러 대신 warning이 발생합니다:
```sql
mysql> INSERT IGNORE INTO t (i) VALUES(1),(1);
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 2 Duplicates: 1 Warnings: 1
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1062 | Duplicate entry '1' for key 't.PRIMARY' |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)
```
예: 테이블 `t2`에
`NOT NULL` 컬럼 `id`가 있는 경우,
strict SQL 모드에서 `NULL`을 insert하면
에러가 발생합니다:
```sql
mysql> CREATE TABLE t2 (id INT NOT NULL);
mysql> INSERT INTO t2 (id) VALUES(1),(NULL),(3);
ERROR 1048 (23000): Column 'id' cannot be null
mysql> SELECT * FROM t2;
Empty set (0.00 sec)
```
SQL 모드가 strict가 아닌 경우,
`IGNORE`는 `NULL`을 컬럼의
implicit default(이 경우 0)로 insert하게 하여,
row를 건너뛰지 않고 처리할 수 있게 합니다:
```sql
mysql> INSERT INTO t2 (id) VALUES(1),(NULL),(3);
mysql> SELECT * FROM t2;
+----+
| id |
+----+
| 1 |
| 0 |
| 3 |
+----+
```
다음 문은 `IGNORE` 키워드를 지원합니다:
- [`CREATE TABLE ... SELECT`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement"):
`IGNORE`는 문의
[`CREATE TABLE`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement") 부분이나
[`SELECT`](https://dev.mysql.com/doc/refman/9.5/en/select.html "15.2.13 SELECT Statement") 부분에 적용되는 것이 아니라,
[`SELECT`](https://dev.mysql.com/doc/refman/9.5/en/select.html "15.2.13 SELECT Statement")에 의해 생성된 row를
테이블에 insert하는 데 적용됩니다.
유니크 키 값이 기존 row와 중복되는 row는 버려집니다.
- [`DELETE`](https://dev.mysql.com/doc/refman/9.5/en/delete.html "15.2.2 DELETE Statement"):
`IGNORE`는 row를 삭제하는 과정에서
발생하는 에러를 MySQL이 무시하도록 합니다.
- [`INSERT`](https://dev.mysql.com/doc/refman/9.5/en/insert.html "15.2.7 INSERT Statement"):
`IGNORE`가 있을 때,
유니크 키 값이 기존 row와 중복되는 row는 버려집니다.
데이터 변환 에러를 유발할 값을 가진 row는
해당 컬럼에 대해 가능한 가장 가까운 유효한 값으로 설정됩니다.
partitioned 테이블에서
주어진 값에 매칭되는 partition을 찾지 못하는 경우,
`IGNORE`는 해당 unmatched 값을 가진 row에 대해
insert 연산이 조용히 실패하도록 합니다.
- [`LOAD DATA`](https://dev.mysql.com/doc/refman/9.5/en/load-data.html "15.2.9 LOAD DATA Statement"),
[`LOAD XML`](https://dev.mysql.com/doc/refman/9.5/en/load-xml.html "15.2.10 LOAD XML Statement"):
`IGNORE`가 있을 때,
유니크 키 값이 기존 row와 중복되는 row는 버려집니다.
- [`UPDATE`](https://dev.mysql.com/doc/refman/9.5/en/update.html "15.2.17 UPDATE Statement"):
`IGNORE`가 있을 때,
유니크 키 값에 대해 duplicate-key conflict가 발생한 row는 update되지 않습니다.
데이터 변환 에러를 유발하는 값으로 update되는 row는
해당 컬럼에 대해 가능한 가장 가까운 유효한 값으로 update됩니다.
`IGNORE` 키워드는 다음과 같은
ignorable 에러에 적용됩니다:
- [`ER_BAD_NULL_ERROR`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_bad_null_error)
- [`ER_DUP_ENTRY`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_dup_entry)
- [`ER_DUP_ENTRY_WITH_KEY_NAME`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_dup_entry_with_key_name)
- [`ER_DUP_KEY`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_dup_key)
- [`ER_NO_PARTITION_FOR_GIVEN_VALUE`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_no_partition_for_given_value)
- [`ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_no_partition_for_given_value_silent)
- [`ER_NO_REFERENCED_ROW_2`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_no_referenced_row_2)
- [`ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_row_does_not_match_given_partition_set)
- [`ER_ROW_IS_REFERENCED_2`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_row_is_referenced_2)
- [`ER_SUBQUERY_NO_1_ROW`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_subquery_no_1_row)
- [`ER_VIEW_CHECK_FAILED`](https://dev.mysql.com/doc/mysql-errors/9.5/en/server-error-reference.html#error_er_view_check_failed)
##### The Effect of Strict SQL Mode on Statement Execution
MySQL 서버는 서로 다른 SQL 모드로 동작할 수 있으며,
[`sql_mode`](https://dev.mysql.com/doc/refman/9.5/en/server-system-variables.html#sysvar_sql_mode)
시스템 변수의 값에 따라
각 클라이언트에 서로 다르게 이러한 모드를 적용할 수 있습니다.
“strict” SQL 모드에서는
서버가 특정 warning을 에러로 상향(upgrade)합니다.
예를 들어,
non-strict SQL 모드에서
문자열 `'abc'`를 정수 컬럼에 insert하면
값이 0으로 변환되고 warning이 발생합니다:
```sql
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t (i) VALUES('abc');
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'abc' for column 'i' at row 1 |
+---------+------+--------------------------------------------------------+
1 row in set (0.00 sec)
```
strict SQL 모드에서는,
invalid 값이 에러와 함께 거부됩니다:
```sql
mysql> SET sql_mode = 'STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t (i) VALUES('abc');
ERROR 1366 (HY000): Incorrect integer value: 'abc' for column 'i' at row 1
```
[`sql_mode`](https://dev.mysql.com/doc/refman/9.5/en/server-system-variables.html#sysvar_sql_mode) 시스템 변수의
설정 가능 값에 대한 자세한 내용은
[Section 7.1.11, “Server SQL Modes”](https://dev.mysql.com/doc/refman/9.5/en/sql-mode.html "7.1.11 Server SQL Modes")를 참조하십시오.
strict SQL 모드는,
값이 범위를 벗어날 수 있거나
invalid row가 테이블에 insert 또는 delete되는 조건에서
다음 문에 적용됩니다:
- [`ALTER TABLE`](https://dev.mysql.com/doc/refman/9.5/en/alter-table.html "15.1.11 ALTER TABLE Statement")
- [`CREATE TABLE`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement")
- [`CREATE TABLE ... SELECT`](https://dev.mysql.com/doc/refman/9.5/en/create-table.html "15.1.24 CREATE TABLE Statement")
- [`DELETE`](https://dev.mysql.com/doc/refman/9.5/en/delete.html "15.2.2 DELETE Statement") (single 테이블과 multiple 테이블 모두)
- [`INSERT`](https://dev.mysql.com/doc/refman/9.5/en/insert.html "15.2.7 INSERT Statement")
- [`LOAD DATA`](https://dev.mysql.com/doc/refman/9.5/en/load-data.html "15.2.9 LOAD DATA Statement")
- [`LOAD XML`](https://dev.mysql.com/doc/refman/9.5/en/load-xml.html "15.2.10 LOAD XML Statement")
- [`SELECT SLEEP()`](https://dev.mysql.com/doc/refman/9.5/en/select.html "15.2.13 SELECT Statement")
- [`UPDATE`](https://dev.mysql.com/doc/refman/9.5/en/update.html "15.2.17 UPDATE Statement") (single 테이블과 multiple 테이블 모두)
스토어드 프로그램 내에서는,
위에서 나열한 유형의 개별 문이
프로그램이 strict 모드에서 정의되었을 경우
strict SQL 모드에서 실행됩니다.
strict SQL 모드는 다음 에러에 적용됩니다.
이 에러들은 입력 값이 invalid하거나 누락된 경우에 해당하는
에러 클래스를 나타냅니다.
값이 컬럼에 대해 잘못된 데이터 타입이거나
범위를 벗어날 수 있는 경우 invalid입니다.
새 row를 insert할 때,
명시적인 `DEFAULT` 절이 없는
`NOT NULL` 컬럼에 대해 값이 주어지지 않은 경우,
그 값은 누락된 값입니다.
```simple
ER_BAD_NULL_ERROR
ER_CUT_VALUE_GROUP_CONCAT
ER_DATA_TOO_LONG
ER_DATETIME_FUNCTION_OVERFLOW
ER_DIVISION_BY_ZERO
ER_INVALID_ARGUMENT_FOR_LOGARITHM
ER_NO_DEFAULT_FOR_FIELD
ER_NO_DEFAULT_FOR_VIEW_FIELD
ER_TOO_LONG_KEY
ER_TRUNCATED_WRONG_VALUE
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
ER_WARN_DATA_OUT_OF_RANGE
ER_WARN_NULL_TO_NOTNULL
ER_WARN_TOO_FEW_RECORDS
ER_WRONG_ARGUMENTS
ER_WRONG_VALUE_FOR_TYPE
WARN_DATA_TRUNCATED
```
**참고**
MySQL 개발이 계속됨에 따라 새로운 에러가 정의되므로,
위 목록에는 없지만 strict SQL 모드가 적용되는
에러가 있을 수 있습니다.
7.1.10 Server Status Variables
7.1.12 Connection Management