2011-09-14 56 views
0

我正在將SQL從一個平臺遷移到另一個平臺。 SQL包含我的目標平臺不支持的DECODE語句。python中的嵌套正則表達式替換

我使用正則表達式來翻譯解碼語句case語句,但我在嵌套的解碼失敗:

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])) 

將匹配

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

解碼的所有出現,並會用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') 

,並返回

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 

有沒有辦法來處理在別人面前最裏面的解碼,這樣我可以用乾淨case語句代替所有的解碼陳述?

+0

嗯......那麼甲骨文是什麼? – NullUserException

+0

這兩個數據庫都不是Oracle:D –

+0

有趣。除了Oracle以外,哪些DB支持'DECODE'? – NullUserException

回答

1

有沒有辦法處理內部解碼之前的其他解碼器,以便我可以乾淨地用case語句替換所有的解碼語句?

是的。

使用((?![^)]*decode).*?)代替嵌套DECODE可以合法出現的任何(.*?)。在循環中運行正則表達式。

請注意,如果存在包含單詞「decode」的字符串(即「THEN值」),則可能會失敗。如果你知道你的數據並且可以排除這種情況,那麼上面的正則表達式就可以滿足你的一次性使用情況。