회사 프로젝트를 진행하면서 SQL문을 작성하는 상황이 많았습니다.
근데 회사 DB 설계에서 칼럼에 예약어를 사용되어 있는 경우가 있었습니다.
예약어를 사용한 칼럼을 조회 시 아래와 같은 에러가 발생할 수 있습니다.
ERROR 1064 (42000): You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near ...
예약어를 사용했기 때문에 문법 에러가 발생하는 것입니다.
이런 문제를 예방하기 위해서는 예약어 리스트를 확인후에 칼럼명을 선정 하는 것이 중요합니다.
ADD | ALL | ALTER |
---|---|---|
ANALYZE | AND | AS |
ASC | ASENSITIVE | BEFORE |
BETWEEN | BIGINT | BINARY |
BLOB | BOTH | BY |
CALL | CASCADE | CASE |
CHANGE | CHAR | CHARACTER |
CHECK | COLLATE | COLUMN |
CONDITION | CONSTRAINT | CONTINUE |
CONVERT | CREATE | CROSS |
CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP |
CURRENT_USER | CURSOR | DATABASE |
DATABASES | DAY_HOUR | DAY_MICROSECOND |
DAY_MINUTE | DAY_SECOND | DEC |
DECIMAL | DECLARE | DEFAULT |
DELAYED | DELETE | DESC |
DESCRIBE | DETERMINISTIC | DISTINCT |
DISTINCTROW | DIV | DOUBLE |
DROP | DUAL | EACH |
ELSE | ELSEIF | ENCLOSED |
ESCAPED | EXISTS | EXIT |
EXPLAIN | FALSE | FETCH |
FLOAT | FLOAT4 | FLOAT8 |
FOR | FORCE | FOREIGN |
FROM | FULLTEXT | GRANT |
GROUP | HAVING | HIGH_PRIORITY |
HOUR_MICROSECOND | HOUR_MINUTE | HOUR_SECOND |
IF | IGNORE | IN |
INDEX | INFILE | INNER |
INOUT | INSENSITIVE | INSERT |
INT | INT1 | INT2 |
INT3 | INT4 | INT8 |
INTEGER | INTERVAL | INTO |
IS | ITERATE | JOIN |
KEY | KEYS | KILL |
LEADING | LEAVE | LEFT |
LIKE | LIMIT | LINES |
LOAD | LOCALTIME | LOCALTIMESTAMP |
LOCK | LONG | LONGBLOB |
LONGTEXT | LOOP | LOW_PRIORITY |
MATCH | MEDIUMBLOB | MEDIUMINT |
MEDIUMTEXT | MIDDLEINT | MINUTE_MICROSECOND |
MINUTE_SECOND | MOD | MODIFIES |
NATURAL | NOT | NO_WRITE_TO_BINLOG |
NULL | NUMERIC | ON |
OPTIMIZE | OPTION | OPTIONALLY |
OR | ORDER | OUT |
OUTER | OUTFILE | PRECISION |
PRIMARY | PROCEDURE | PURGE |
READ | READS | REAL |
REFERENCES | REGEXP | RELEASE |
RENAME | REPEAT | REPLACE |
REQUIRE | RESTRICT | RETURN |
REVOKE | RIGHT | RLIKE |
SCHEMA | SCHEMAS | SECOND_MICROSECOND |
SELECT | SENSITIVE | SEPARATOR |
SET | SHOW | SMALLINT |
SONAME | SPATIAL | SPECIFIC |
SQL | SQLEXCEPTION | SQLSTATE |
SQLWARNING | SQL_BIG_RESULT | SQL_CALC_FOUND_ROWS |
SQL_SMALL_RESULT | SSL | STARTING |
STRAIGHT_JOIN | TABLE | TERMINATED |
THEN | TINYBLOB | TINYINT |
TINYTEXT | TO | TRAILING |
TRIGGER | TRUE | UNDO |
UNION | UNIQUE | UNLOCK |
UNSIGNED | UPDATE | USAGE |
USE | USING | UTC_DATE |
UTC_TIME | UTC_TIMESTAMP | VALUES |
VARBINARY | VARCHAR | VARCHARACTER |
VARYING | WHEN | WHERE |
WHILE | WITH | WRITE |
XOR | YEAR_MONTH | ZEROFILL |
위 토글을 펼쳐보면 MySQL에서 사용하는 예약어 리스트를 확인 할 수 있습니다.
이런 예약어를 꼭 피해서 칼럼명을 선정해야 합니다.
만약에 이미 예약어를 사용 했으면 아래의 방법을 통해 해결할 수 있습니다.
SELECT "DESC" FROM table_name; -- SQL 표준 인용 부호
SELECT `DESC` FROM table_name; -- MySQL 백틱 사용
위와 같이 쿼리문 작성 시 백틱을 붙이거나 SQL 표준 인용 부호를 붙이면 쉽게 해결됩니다.
아주 간단한 방법으로 해결 할 수 있는 문제입니다.
하지만 이런 사소한 실수가 유지보수성을 엄청나게 떨어트린 다는 것을 알 수 있습니다.
이 문제는 컴파일 과정이 아닌 런타임 환경에서 발생할 수 있는 에러입니다.
JPA, Entity Framework와 같은 ORM을 사용한다고 해도 런타임 환경에서 에러가 발생합니다.
SQL Syntax 에러로 나오기 때문에 쿼리문 중에 어디가 문제가 있는지 하나씩 다 읽어보고 확인해 백틱을 붙여줘야 합니다.
(JPA는 Entity에 정의되어 있는 예약어 칼럼에 어노테이션을 추가해 해야 합니다.)
설계된 DB는 쉽게 변경이 힘들기 때문에 유지보수의 고통이 모두에게 되물림 될 수 있습니다.