用python去除SQL中的注释

打印 上一主题 下一主题

主题 890|帖子 890|积分 2670

我的博客
在看到这个标题时候肯定有人会想,我写SQL直接在数据库工具上执行就行了啊,工具会自动识别注释的,就是不用工具,把SQL写到存储过程里,数据库也会识别注释不执行的,干嘛非要去掉,费力不讨好。

其实是最近在做一个项目,需要在行云库里执行SQL,并且SQL是写在脚本上的,通过JDBC调用,众所周知,SQL的注释很随意,甚至有什么保佑不出bug这种,那么执行的时候就很有可能因为注释里的特殊字符导致一堆莫名其妙的bug出现,并且行云数据库是一个国产的不太完善的数据库,所以本身对特殊字符的支持也不是很好,所以去除注释势在必行。

好了,废话说的够多了,现在上代码,因为行注释和段落注释使用的注释方法不同,所以这里分成两个功能来写
  1. # 去除行注释
  2. # 说明:因为行注释是从--开始一直到结尾都算行注释,所以一个正则就可以搞定了
  3. def rehint_line(sql_values):
  4.   rev = re.compile('--.*\\n?')
  5.   sql_values = re.sub(rev,'\n',sql_values)
  6.   return sql_values
复制代码
行注释看起来还是比较简单的,其实我也没想到会这么简单,哈哈哈哈哈
  1. # 去除段注释
  2. '''
  3. 说明:
  4.   1、在读取SQL的时候需要一次全部读出来,然后赋值给变量
  5.   2、迭代读取SQL中的每一个字符,并且把字符写到新的变量里
  6.   3、如果遇到/或*就记录下,例如给变量v
  7.   4、当遇到/之后,紧跟着下一个字符是*,那就停止把字符写到变量,直到遇到*之后紧跟着下一个字符是/
  8. '''
  9. def rehint_limit(sql_values):
  10.   write_tag = 0 # 用来控制是否写入新变量
  11.   write_limit = '' # 记录/或者*
  12.   sql_result = '' # 记录去除注释后的结果
  13.   for case in sql_values:
  14.     if (write_limit + case) == '/*':
  15.       sql_result = sql_result.strip('/') # 去除最后一个/
  16.       write_tag += 1
  17.     if write_tag == 0:
  18.       sql_result += case
  19.     if (write_limit + case) == '*/':
  20.       write_tag -= 1
  21.     write_limit = ''
  22.     if '/' == case or '*' == case:
  23.       write_limit = case
  24.   return sql_result
复制代码
恩,段注释有一些麻烦,不过还好,我写说明了,如果大家有更好更有效率的办法欢迎提供

下面试下效果,把下面代码存成rehint.py,或者你想存成别的也行,名字随意啦
  1. #!/usr/bin/python
  2. # coding: utf-8
  3. import re
  4. def rehint_limit(sql_values):
  5.   write_tag = 0 # 用来控制是否写入新变量
  6.   write_limit = '' # 记录/或者*
  7.   sql_result = '' # 记录去除注释后的结果
  8.   for case in sql_values:
  9.     if (write_limit + case) == '/*':
  10.       sql_result = sql_result.strip('/') # 去除最后一个/
  11.       write_tag += 1
  12.     if write_tag == 0:
  13.       sql_result += case
  14.     if (write_limit + case) == '*/':
  15.       write_tag -= 1
  16.     write_limit = ''
  17.     if '/' == case or '*' == case:
  18.       write_limit = case
  19.   return sql_result
  20. def rehint_line(sql_values):
  21.   rev = re.compile('--.*\\n?')
  22.   sql_values = re.sub(rev,'\n',sql_values)
  23.   return sql_values
  24. if __name__ == '__main__':
  25.   sql = '''
  26. --这是个sql
  27. select '1' v1,'2' v2 from dual union all
  28. select '2' v1,'3' v2 from dual union all
  29. /* 这段select 1 v1,2 v2 from dual union all
  30. select 2 v1,3 v2 from dual 写错了
  31. */
  32. select /* 这个是select语句 */ 'a' v1, --v1列
  33.        'b' v2 --v2列
  34. from dual --dual是个伪表
  35. '''
  36.   print(sql)
  37.   # 先去除段注释
  38.   sql = rehint_limit(sql)
  39.   print('rehint_limit: ' + sql)
  40.   # 去除行注释
  41.   sql = rehint_line(sql)
  42.   print('rehint_line: ' + sql)
复制代码
执行结果见截图

效果和预想的结果一样,注释去除的干干净净
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立聪堂德州十三局店

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表