회사 업무를 진행하던 중 특정 쿼리를 수행할 때 아래와 같은 오류가 발생했다.
Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation '=’
각 테이블, 컬럼마다 UTF8 과 같은 collation 값이 설정되는데,
문제가 발생한 쿼리의 JOIN 절에서 비교한 컬럼 끼리 collation 값이 서로 일치하지 않아서 발생하는 오류였다.
DB에서 사용하기로 약속한 collation 설정 값은 "utf8mb4_general_ci" 이기 때문에
"utf8mb4_0900_ai_ci" 값으로 설정되어 있는 테이블과 컬럼의 collation 값을 수정하였다.
SHOW TABLE STATUS WHERE NAME LIKE <테이블명>;
ALTER TABLE <테이블명> DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
SHOW FULL COLUMNS FROM table_name;
ALTER TABLE <테이블명> MODIFY COLUMN <컬럼명> <컬럼타입> COLLATE utf8mb4_general_ci
위와 같이 수정하고 다시 테스트 해보니 아래와 같이 다른 부분에서 동일한 오류가 발생했다.
Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation 'instr’
문제가 되었던 쿼리는 아래의 SELECT 절에서 특정 함수를 통해 값을 가져오는 부분에서 오류가 발생 했다.
select instr(fn_get_board_dir_navi_lang(bd.top_level, bc.comp_id, 'kr'), '>')
from board_category bc
left join board_directory bd on bc.comp_id = bd.comp_id and bc.cat_seq_no = bd.cat_seq_no
오류 원인은 instr 함수에서 fn_get_board_dir_navi_lang 함수의 결과 값과 비교문자 '>' 를 비교할 때
비교문자 '>' 은 현재 DB의 기본 Collation 값인 "utf8mb4_general_ci" 이지만, 함수의 결과값은 "utf8mb4_0900_ai_ci" 이어서 충돌이 발생한 것이었다.
최초 오류사항을 해결할 때 모든 테이블과 컬럼의 collation 설정 값을 모두 "utf8mb4_general_ci" 으로 맞춰 주어서
해당 테이블과 컬럼을 사용하는 "fn_get_board_dir_navi_lang" 함수도 같이 적용 되었을것이라 생각했지만
확인해보니 함수의 collation은 생성 당시 테이블 , 컬럼의 collation 설정을 따라 가고 있었다.
즉, 함수 생성 당시 내부에 정의된 테이블의 collation이 "utf8mb4_0900_ai_ci" 이었기 때문에
생성 이후에 해당 테이블의 collation 값을 변경한다고 해도 생성 당시의 collation 값인 "utf8mb4_0900_ai_ci" 형태로 결과값을 리턴하고 있엇던 것이다.
해결 방법으로는 해당 함수를 삭제 한 뒤 재생성하였다.
위에 내용까지 수정하고 실 서버로 확인 했을때는 오류가 더이상 발생하지 않았다.
하지만 이상하게 로컬에서는 동일한 쿼리에서 오류가 발생하고 있었다.
Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation 'instr’
오류의 내용은 함수의 리턴값은 utf8mb4_general_ci 타입이지만, 비교 연산자 역할을 하는 '>' 값이 utf8mb4_0900_ai_ci 타입이었다.
실서버에서는 정상작동하는데 로컬에서는 안되는 이유를 찾아보니
로컬 PC에서 DB를 연결할 때도 collation 설정을 해주는 부분이 있었다.
별도로 설정을 안하고 로컬에서 DB에 붙어서 사용하니까 로컬에서 사용하는 DB의 기본 collation 설정값이 utf8mb4_0900_ai_ci 으로 기본 설정되었고, 비교 문자 '>' 값도 해당 collation으로 조회되었다.
IDE로 인텔리제이를 사용하고 있었기 때문에, IntelliJ DB 연결 설정 부분을 수정해서 재 접속하였다.