2011-09-14 7 views
0

하나의 플랫폼에서 다른 플랫폼으로 SQL을 마이그레이션하려고합니다. SQL에는 내 대상 플랫폼에서 지원하지 않는 DECODE 문이 포함되어 있습니다. 것파이썬에서 중첩 된 정규 표현식 대체

select decode(dim1,'','-',dim1) as myfield1, decode(dim2,'','-',dim2') as myfield2 

에 디코드의 모든 항목을 일치합니다

import re 
sql_frag = "select decode(dim1,'','-',dim1) as myfield1, decode(dim2,'','-',dim2') as myfield2" 
reg=re.compile("(decode\((.*?),(.*?),(.*?),(.*?)\))",re.IGNORECASE) 

matches = reg.findall(sql_frag) 
for match in matches: 
sql_frag = sql_frag.replace(match[0],'case when %s = %s then %s else %s end' % (match[1],match[2],match[3],match[4])) 

과 :

나는 case 문에 디코드 문을 번역하는 정규 표현식을 사용하고 있지만 중첩 된 디코딩에 실패 해요 사례 설명으로 바꾸기 :

select case when dim1 = '' then '-' else dim1 end as myfield1, case when dim2 = '' then '-' else dim2' end as myfield2 

하지만 코드는 중첩 된 상태로 이동합니다. 디코드 문 :

sql_frag="select decode(f1,3,4,decode(f2,5,4,f2)) as myfield, decode(foo,bar,baz,foo) as myfield2" 

>>> reg.findall(sql_frag) 
[('decode(f1,3,4,decode(f2,5,4,f2)', 'f1', '3', '4', 'decode(f2,5,4,f2'), ('decode(foo,bar,baz,foo)', 'foo', 'bar', 'baz', 'foo') 

와 내가 깨끗하게 case 문으로 디코드 문을 모두 장착 할 수 있도록 다른 사람 전에 가장 안쪽의 디코딩을 처리 할 수있는 방법이 있나요

select case when f1 = 3 then 4 else decode(f2,5,4,f2 end) as myfield, case when foo = bar then baz else foo end as myfield2 

반환?

+0

흠 ... 그럼 오라클에는 어떤 것이 있습니까? – NullUserException

+0

어느 데이터베이스도 오라클 : D –

+0

흥미 롭습니다. 어떤 DB가 오라클 외에'DECODE '를 지원합니까? – NullUserException

답변

1

다른 모든 것보다 가장 안쪽의 디코드를 처리하여 모든 디코드 문을 case 문으로 완전히 대체 할 수있는 방법이 있습니까?

예.

중첩 된 DECODE이 합법적으로 발생할 수있는 (.*?) 대신에 ((?![^)]*decode).*?)을 사용하십시오. 루프에서 정규식을 실행하십시오.

'디코드'라는 단어가 포함 된 문자열 (예 : "THEN 값")이 있으면이 작업이 실패 할 수 있습니다. 데이터를 알고이 사례를 배제 할 수있는 경우 위의 정규식 접근 방식은 일회용 사례로 충분합니다.