Loading...
MySQL 9.5 Reference Manual 9.5의 13.1.7 Out-of-Range and Overflow Handling의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MySQL이 숫자 column에 대해 허용 범위를 벗어난 값을 저장할 때의 결과는, 그 시점에 적용 중인 SQL mode에 따라 달라집니다:
strict SQL mode가 활성화되어 있으면, MySQL은 범위 초과 값을 에러와 함께 거부하고 insert가 실패합니다. 이는 SQL 표준에 부합합니다.
제한적인 mode가 활성화되어 있지 않으면, MySQL은 값을 column 데이터 타입 범위의 적절한 끝값으로 잘라서(clipping) 대신 그 결과 값을 저장합니다.
범위 초과 값이 integer column에 할당되면, MySQL은 column 데이터 타입 범위의 해당 끝값을 나타내는 값을 저장합니다.
floating-point 또는 fixed-point column에 대해, 지정된(또는 기본) precision과 scale이 암시하는 범위를 초과하는 값이 할당되면, MySQL은 그 범위의 해당 끝값을 나타내는 값을 저장합니다.
table t1이 다음과 같이 정의되어 있다고 가정합니다:
1CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);
strict SQL mode가 활성화된 상태에서는, 범위 초과 에러가 발생합니다:
1mysql> SET sql_mode = 'TRADITIONAL'; 2mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256); 3ERROR 1264 (22003): Out of range value for column 'i1' at row 1 4mysql> SELECT * FROM t1; 5Empty set (0.00 sec)
strict SQL mode가 활성화되지 않은 상태에서는, 경고와 함께 clipping이 발생합니다:
1mysql> SET sql_mode = ''; 2mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256); 3mysql> SHOW WARNINGS; 4+---------+------+---------------------------------------------+ 5| Level | Code | Message | 6+---------+------+---------------------------------------------+ 7| Warning | 1264 | Out of range value for column 'i1' at row 1 | 8| Warning | 1264 | Out of range value for column 'i2' at row 1 | 9+---------+------+---------------------------------------------+ 10mysql> SELECT * FROM t1; 11+------+------+ 12| i1 | i2 | 13+------+------+ 14| 127 | 255 | 15+------+------+
strict SQL mode가 활성화되지 않은 경우, clipping으로 인해 발생하는 column 할당 변환은 ALTER TABLE,
LOAD DATA,
UPDATE, 그리고 multi-row
INSERT statement에 대해 warning으로 보고됩니다. strict mode에서는 이러한 statement가 실패하며, table이 트랜잭션 테이블인지 여부와 기타 요인에 따라 일부 또는 전체 값이 insert되거나 변경되지 않습니다. 자세한 내용은
Section 7.1.11, “Server SQL Modes”를 참조하십시오.
numeric expression 평가 중 overflow가 발생하면 에러가 발생합니다. 예를 들어, signed
BIGINT의 최댓값은 9223372036854775807이므로, 다음 expression은 에러를 생성합니다:
1mysql> SELECT 9223372036854775807 + 1; 2ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
이 경우 연산이 성공하도록 하려면, 값을 unsigned로 변환하십시오:
1mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1; 2+-------------------------------------------+ 3| CAST(9223372036854775807 AS UNSIGNED) + 1 | 4+-------------------------------------------+ 5| 9223372036854775808 | 6+-------------------------------------------+
overflow가 발생하는지는 operand의 범위에 따라 달라지므로, 앞선 expression을 처리하는 또 다른 방법은 exact-value arithmetic을 사용하는 것입니다. 이는
DECIMAL 값이 integer보다 더 큰 범위를 갖기 때문입니다:
1mysql> SELECT 9223372036854775807.0 + 1; 2+---------------------------+ 3| 9223372036854775807.0 + 1 | 4+---------------------------+ 5| 9223372036854775808.0 | 6+---------------------------+
integer 값들 사이의 subtraction에서, 그중 하나가 UNSIGNED 타입인 경우, 기본적으로 결과는 unsigned가 됩니다. 결과가 원래는 음수가 되었을 상황이라면, 에러가 발생합니다:
1mysql> SET sql_mode = ''; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> SELECT CAST(0 AS UNSIGNED) - 1; 5ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
NO_UNSIGNED_SUBTRACTION
SQL mode가 활성화되어 있으면, 결과는 음수가 됩니다:
1mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION'; 2mysql> SELECT CAST(0 AS UNSIGNED) - 1; 3+-------------------------+ 4| CAST(0 AS UNSIGNED) - 1 | 5+-------------------------+ 6| -1 | 7+-------------------------+
이러한 연산의 결과가 UNSIGNED integer column을 업데이트하는 데 사용되면, 결과는 column 타입의 최대값으로 잘리거나, NO_UNSIGNED_SUBTRACTION
이 활성화된 경우 0으로 잘립니다. strict SQL mode가 활성화되어 있으면, 에러가 발생하고 column은 변경되지 않은 상태로 유지됩니다.
13.1.6 Numeric Type Attributes
13.2 Date and Time Data Types