월이나 일이 0인 날짜, 왜 저장이 필요할까?
실무에서는 연도만 알고 정확한 월이나 일을 모르는 경우가 종종 있습니다. 예를 들어 '2017년 어느 시점'처럼 불완전한 날짜 정보를 데이터베이스에 그대로 보관하고 싶다면, 월(month)이나 일(day) 자리에 0을 넣어 저장할 수 있어야 합니다.
다만 MySQL의 기본 설정에서는 이러한 날짜를 유효하지 않은 값으로 판단하여 저장을 거부합니다. 따라서 SQL 모드를 allow_invalid_dates로 변경해 주어야 합니다.
1. allow_invalid_dates 모드 설정
mysql> set sql_mode = 'allow_invalid_dates'; Query OK, 0 rows affected (0.00 sec)
모드 설정이 완료되면, 월과 일이 모두 0인 날짜부터 순서대로 저장해 보겠습니다.
월과 일이 모두 0인 날짜 저장
mysql> insert into check_date(OrderDate) values('2017-00-00');
Query OK, 1 row affected (0.06 sec)
mysql> select * from check_date;
+-------------+
| OrderDate |
+-------------+
| 2017-00-00 |
+-------------+
1 row in set (0.00 sec)위 쿼리는 월과 일 값이 모두 0인 날짜, 즉 '연도만 알고 있는' 날짜를 성공적으로 삽입합니다.
월이 0인 날짜 저장
mysql> insert into check_date(Orderdate) values ('2017-00-05');
Query OK, 1 row affected (0.07 sec)
mysql> select * from check_date;
+------------+
| Orderdate |
+------------+
| 2017-00-00 |
| 2017-00-05 |
+------------+
2 rows in set (0.00 sec)위 쿼리는 월 값이 0이고 일 값은 존재하는 날짜를 삽입합니다.
일이 0인 날짜 저장
mysql> insert into check_date(Orderdate) values ('2017-05-00');
Query OK, 1 row affected (0.02 sec)
mysql> select * from check_date;
+------------+
| Orderdate |
+------------+
| 2017-00-00 |
| 2017-00-05 |
| 2017-05-00 |
+------------+
3 rows in set (0.00 sec)위 쿼리는 월은 존재하지만 일 값이 0인 날짜를 삽입합니다. 이처럼 allow_invalid_dates 모드를 사용하면 연도·월·일 중 일부만 알고 있는 불완전한 날짜 데이터도 자유롭게 저장할 수 있습니다.
사용 시 주의사항
allow_invalid_dates 모드는 말 그대로 '유효하지 않은 날짜'까지 허용하므로, 실수로 잘못된 날짜(예: 2월 30일)가 입력될 가능성도 열어둡니다. 따라서 데이터 품질이 중요한 운영 환경에서는 필요한 세션에 한해서만 설정하거나, 애플리케이션 단에서 입력값 검증을 함께 수행하는 것이 안전합니다. 작업이 끝난 후에는 set sql_mode = ''; 또는 기존 모드로 되돌려 원래 설정을 복원하는 것을 권장합니다.