ruby

ActiveRecord, ORA-01795

ActiveRecord 이용한 프로그램 짜던 중 안 풀리는 문제가 있어서 Ruby 포럼에 질문 올린 후 답변도 없고 당장 중요한 작업도 아니어서 제쳐놓고 있다가 간만에 다시 소스보다가 의외로 간단하게 해결해서 기록 남겨본다.

find 메서드의 조건으로 scala 객체가 넘겨지면 SQL 로 전환시 Where 절의 ‘=’ 구문으로, Collection 객체가 넘겨지면 ‘IN’ 구문으로 변환됩니다.
그런데 Collection 객체의 크기가 1,000이 넘으면 즉, ‘IN’ 조건에 들어갈 변수값이 1,000개가 넘으면 Oracle DB 의 경우 ‘OCIError: ORA-01795: maximum number of expressions in a list is 1000’ 란 에러가 납니다.

저같은 경우 선행해서 구한 ActiveRecord Collection 타입의 값을 직접 다음 find 메서드의 조건값으로 넘겨주려다 이 에러 만나서 질문할 때만 해도 먼저 얻었던 ActiveRecord Collection 객체를 일정 크기로 잘라서 어찌해볼까 하고 있었죠.

그런데 간만에 다시 들여다보니 의외로 쉬운 방법이 보이더군요.
1. ActiveRecord Collection 객체 때문에 고민하지말고 실제 ‘IN’ 조건에 쓰일 값만 사용하기위해 collect 메서드를 이용하여 필요값들만 Array 객체에 담는다.
2. max보다 큰 경우 max개씩 잘라서 find 메서드 실행하고 그렇게해서 얻어진 ActiveRecord Collection 값들을 concat 을 이용해서 합친다.
아래는 이렇게 구현된 샘플입니다.

def get_data(arr_list)
    find :all, :conditions => { :… => arr_list }
end

arr_list = pre_rs.collect {|row| row.col_name }

arr_size = arr_list.size
max_list = 1000.0

if arr_size <= max_list
    res = get_data(arr_list)
else
    res = Array.new
   1.step(ar_size, max_list) do |i|
        res = res.concat get_data(arr_list[i – 1, max_list])
   end
end

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s