MySQL에서 예약어를 테이블 또는 열 이름으로 사용하여 발생하는 구문 오류
다음과 같이 간단한 MySQL 쿼리를 실행하려고합니다.
INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
하지만 다음과 같은 오류가 발생합니다.
오류 1064 (42000) : SQL 구문에 오류가 있습니다. MySQL 서버 버전에 해당하는 설명서
'key) VALUES ('Tim', 'Florida', 42)'
에서 1 행 근처 에서 사용할 올바른 구문을 확인하십시오.
문제를 어떻게 해결할 수 있습니까?
답변
# 문제
MySQL의에서 특정 단어 좋아 SELECT
, INSERT
, DELETE
등 예약 된 단어입니다. 특별한 의미가 있기 때문에 MySQL은 식별자를 백틱으로 묶지 않는 한 테이블 이름, 열 이름 또는 다른 종류의 식별자로 사용할 때마다 구문 오류로 처리합니다.
공식 문서에서 언급했듯이 섹션 10.2 Schema Object Names (강조 추가됨) :
데이터베이스, 테이블, 인덱스, 열, 별칭, 뷰, 저장 프로 시저, 파티션, 테이블 스페이스 및 기타 개체 이름을 비롯한 MySQL 내의 특정 개체를 식별자라고 합니다.
...
식별자에 특수 문자가 포함되어 있거나 예약어 인 경우 참조 할 때마다 따옴표 를 사용해야 합니다.
...
식별자 인용 문자는 백틱 ( "
`
")입니다.
키워드 및 예약어의 전체 목록은 섹션 10.3 키워드 및 예약어 에서 찾을 수 있습니다 . 이 페이지에서 "(R)"뒤에 오는 단어는 예약어입니다. 이 문제를 일으키는 많은 예약어를 포함하여 일부 예약어가 아래에 나열되어 있습니다.
- 더하다
- 과
- 전에
- 으로
- 요구
- 케이스
- 질환
- 지우다
- DESC
- 설명
- 에서
- 그룹
- 에
- 인덱스
- 끼워 넣다
- 간격
- IS
- 키
- 처럼
- 한도
- 긴
- 시합
- 아니
- 선택권
- 또는
- 주문
- 분할
- 참고 문헌
- 고르다
- 표
- 에
- 최신 정보
- 어디
#해결책
두 가지 옵션이 있습니다.
1. 예약어를 식별자로 사용하지 마십시오.
가장 간단한 해결책은 예약어를 식별자로 사용하지 않는 것입니다. 예약어가 아닌 열에 대한 또 다른 합리적인 이름을 찾을 수 있습니다.
이렇게하면 몇 가지 장점이 있습니다.
특정 식별자가 예약어라는 사실을 잊어 버리거나 모르기 때문에 사용자 또는 데이터베이스를 사용하는 다른 개발자가 실수로 구문 오류를 작성할 가능성을 제거합니다. MySQL에는 많은 예약어가 있으며 대부분의 개발자는 모든 예약어를 알지 못합니다. 처음에 이러한 단어를 사용하지 않으면 자신이나 미래의 개발자에게 함정을 남기지 않습니다.
식별자 인용 방법은 SQL 언어마다 다릅니다. MySQL은 기본적으로 식별자 인용에 백틱을 사용하지만 ANSI 호환 SQL (그리고 여기에 언급 된대로 실제로 ANSI SQL 모드의 MySQL )은 식별자 인용에 큰 따옴표를 사용합니다. 따라서 백틱으로 식별자를 인용하는 쿼리는 다른 SQL 언어로 쉽게 이식 할 수 없습니다.
순전히 향후 실수의 위험을 줄이기 위해 식별자를 역 따옴표로 인용하는 것보다 일반적으로 현명한 조치입니다.
2. 백틱 사용
테이블 또는 열의 이름을 변경할 수없는 경우 10.2 Schema Object Names`
의 이전 인용문에 설명 된대로 문제가되는 식별자를 백틱 ( )으로 묶습니다 .
사용법을 보여주는 예 ( 10.3 키워드 및 예약어에서 가져옴 ) :
mysql> CREATE TABLE interval (begin INT, end INT); ERROR 1064 (42000): You have an error in your SQL syntax. near 'interval (begin INT, end INT)'
mysql> CREATE TABLE
interval
(begin INT, end INT); Query OK, 0 rows affected (0.01 sec)
마찬가지로 질문의 쿼리는 key
아래와 같이 백틱으로 키워드 를 래핑하여 수정할 수 있습니다 .
INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)"; ^ ^