oracle varchar2 -> CLOB 타입 변경 오류 해결하기

임현규·2023년 7월 14일
0

Meca project 개발 일지

목록 보기
25/27

문제 요약

이번에 카드 엔티티의 질문(Question) 속성과 설명(Description) 속성의 허용 길이를 늘려달라고 부탁받았다. Description의 경우 원래 CLOB이기에 큰 문제 없었지만 질문속성의 경우 VARCHAR2(2000)으로 정의되어있었다. 이를 5만자로 허용하기 위해서는 CLOB으로 변환해야 했다. 그래서 application code를 수정하고 validate -> update로 hibernate:ddl-auto를 수정했는데 application 시작에는 큰 문제가 없었지만 조회시 다음과 같은 에러가 발생했다.

2023-07-14 18:07:06.010  WARN 1 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 17004, SQLState: 99999
2023-07-14 18:07:06.013 ERROR 1 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : Invalid column type: getCLOB not implemented for class oracle.jdbc.driver.T4CVarcharAccessor
2023-07-14 18:07:06.016 ERROR 1 --- [nio-8080-exec-6] a.m.c.e.GlobalControllerExceptionHandler : could not execute query; nested exception is org.hibernate.exception.GenericJDBCException: could not execute query

쿼리를 실행할수 없고 invalid column type이라 쿼리할 수 없다는 것이였다.

그래서 실제 db장소인 oracle cloud를 확인해보니 CLOB이 아닌 VARCHAR2로 설정되어 있었다. 그래서 타입을 직접 수정하려고 하니 다음과 같은 에러가 발생했다.

임시 컬럼을 생성해 문제 해결하기

직접 바꾸는 것은 불가능하다. 그렇다면 타입을 안전하게 바꾸는 방법은 없을까? 불가능하지 않다.

혹시 문제를 풀면서 서로 변수를 스왑할 때를 기억하는가?

  1. 임시 변수를 만들고 거기에 잠깐 저장해둔다
  2. 변수를 스왚한다
  3. 나머지 변수에 임시 변수를 할당한다.

이런 아이디어를 생각해서 적용하면 컬럼을 안전하게 교체할 수 있다.
우선 아이디어는 다음과 같다.

  1. 원하는 타입(CLOB)의 임시 컬럼을 생성한다.
  2. 임시 컬럼에 기존 컬럼 데이터를 복사한다.(update)
  3. 기존 컬럼을 삭제한다
  4. 임시 컬럼을 기존 컬럼으로 컬럼 네임을 수정한다

이와 같이 적용하기 위해서 사용하는 SQL은 다음과 같다.

alter table card add (tmp_question CLOB);

update card set tmp_question = QUESTION;
commit;

alter table card drop column question;

alter table card rename column tmp_question to question;

그 결과 성공적으로 별다른 데이터 문제 없이 Question(VARCHAR2(2000) -> CLOB)컬럼 변경에 성공했고 문제없이 잘 동작했다.

참고 블로그

https://ubermensch-with.tistory.com/352

profile
엘 프사이 콩그루

0개의 댓글