我的博客在看到這個標題時候肯定有人會想,我寫SQL直接在資料庫工具上執行就行了啊,工具會自動識別註釋的,就是不用工具,把SQL寫到存儲過程里,資料庫也會識別註釋不執行的,幹嘛非要去掉,費力不討好。 其實是最近在做一個項目,需要在行雲庫里執行SQL,並且SQL是寫在腳本上的,通過JDBC調用,眾所周知 ...
我的博客
在看到這個標題時候肯定有人會想,我寫SQL直接在資料庫工具上執行就行了啊,工具會自動識別註釋的,就是不用工具,把SQL寫到存儲過程里,資料庫也會識別註釋不執行的,幹嘛非要去掉,費力不討好。
其實是最近在做一個項目,需要在行雲庫里執行SQL,並且SQL是寫在腳本上的,通過JDBC調用,眾所周知,SQL的註釋很隨意,甚至有什麼保佑不出bug這種,那麼執行的時候就很有可能因為註釋里的特殊字元導致一堆莫名其妙的bug出現,並且行雲資料庫是一個國產的不太完善的資料庫,所以本身對特殊字元的支持也不是很好,所以去除註釋勢在必行。
好了,廢話說的夠多了,現在上代碼,因為行註釋和段落註釋使用的註釋方法不同,所以這裡分成兩個功能來寫
# 去除行註釋 # 說明:因為行註釋是從--開始一直到結尾都算行註釋,所以一個正則就可以搞定了 def rehint_line(sql_values): rev = re.compile('--.*\\n?') sql_values = re.sub(rev,'\n',sql_values) return sql_values
行註釋看起來還是比較簡單的,其實我也沒想到會這麼簡單,哈哈哈哈哈
# 去除段註釋 ''' 說明: 1、在讀取SQL的時候需要一次全部讀出來,然後賦值給變數 2、迭代讀取SQL中的每一個字元,並且把字元寫到新的變數里 3、如果遇到/或*就記錄下,例如給變數v 4、當遇到/之後,緊跟著下一個字元是*,那就停止把字元寫到變數,直到遇到*之後緊跟著下一個字元是/ ''' def rehint_limit(sql_values): write_tag = 0 # 用來控制是否寫入新變數 write_limit = '' # 記錄/或者* sql_result = '' # 記錄去除註釋後的結果 for case in sql_values: if (write_limit + case) == '/*': sql_result = sql_result.strip('/') # 去除最後一個/ write_tag += 1 if write_tag == 0: sql_result += case if (write_limit + case) == '*/': write_tag -= 1 write_limit = '' if '/' == case or '*' == case: write_limit = case return sql_result
恩,段註釋有一些麻煩,不過還好,我寫說明瞭,如果大家有更好更有效率的辦法歡迎提供
下麵試下效果,把下麵代碼存成rehint.py,或者你想存成別的也行,名字隨意啦
#!/usr/bin/python # coding: utf-8 import re def rehint_limit(sql_values): write_tag = 0 # 用來控制是否寫入新變數 write_limit = '' # 記錄/或者* sql_result = '' # 記錄去除註釋後的結果 for case in sql_values: if (write_limit + case) == '/*': sql_result = sql_result.strip('/') # 去除最後一個/ write_tag += 1 if write_tag == 0: sql_result += case if (write_limit + case) == '*/': write_tag -= 1 write_limit = '' if '/' == case or '*' == case: write_limit = case return sql_result def rehint_line(sql_values): rev = re.compile('--.*\\n?') sql_values = re.sub(rev,'\n',sql_values) return sql_values if __name__ == '__main__': sql = ''' --這是個sql select '1' v1,'2' v2 from dual union all select '2' v1,'3' v2 from dual union all /* 這段select 1 v1,2 v2 from dual union all select 2 v1,3 v2 from dual 寫錯了 */ select /* 這個是select語句 */ 'a' v1, --v1列 'b' v2 --v2列 from dual --dual是個偽表 ''' print(sql) # 先去除段註釋 sql = rehint_limit(sql) print('rehint_limit: ' + sql) # 去除行註釋 sql = rehint_line(sql) print('rehint_line: ' + sql)
執行結果見截圖
效果和預想的結果一樣,註釋去除的乾乾凈凈