利用python对SQL语句进行解析

        在数据库管理和数据分析领域,SQL查询是一个常见的工具。有时,我们需要从SQL查询中提取表名和视图名,以便进一步的处理和分析。在本文中,将介绍如何使用Python编写代码来实现这一目标。

步骤0:环境准备

        需要利用sqlparse库和re库,本质上就是利用sqlparse的SQL语句解析功能和re正则表达式对SQL中的物理表和视图名字:

pip install sqlparse
pip install re

步骤1:SQL语句格式化

        首先,我们需要对SQL语句进行格式化,以确保它在解析之前具有一致的结构。这包括去除注释和不必要的空白。

def format_sql(sql_content):
    '''将SQL语句进行规范化,并去除SQL中的注释,输入和输出均为字符串'''
    parse_str = sqlparse.format(sql_content.strip(), reindent=True, strip_comments=True)
    return parse_str

步骤2:解析SQL语句

        使用sqlparse库来解析SQL语句,然后通过正则表达式来匹配表名和视图名。以下是用于从SQL语句中提取表名和视图名的Python函数:

def extract_table_names(sql_query):
    '''从SQL中提取表名称,输出为列表'''
    table_names = set()
    # 解析SQL语句
    parsed = sqlparse.parse(sql_query)
    # 正则表达式模式,用于匹配表名
    table_name_pattern = r'\bFROM\s+([^\s\(\)\,]+)|\bJOIN\s+([^\s\(\)\,]+)|(\[jntm\w+\])|(\[abc\w+\])'
    
    # 遍历解析后的语句块
    for statement in parsed:
        # 转换为字符串
        statement_str = str(statement).lower()
        
        # 更多处理和清理步骤
        # ...
        
        # 查找匹配的表名
        matches = re.findall(table_name_pattern, statement_str, re.IGNORECASE)
        
        for match in matches:
            for name in match:
                if name:
                    # 处理可能包含命名空间的情况
                    table_name = name.split('.')[-1]
                    table_name = re.sub('("|`|\'|;)', '', table_name)
                    table_names.add(table_name)
    
    # 更多自定义处理
    # ...
    
    return list(table_names)

       这里正则表达式的编写比较重要,直接影响了最后的筛选效果,我们需要主要对正则表达式进行自定义编写,单纯的使用sqlparse会导致效果非常差。

table_name_pattern = r'\bFROM\s+([^\s\(\)\,]+)|\bJOIN\s+([^\s\(\)\,]+)|(\[jntm\w+\])|(\[abc\w+\])'

步骤3:主函数体

在主函数中,我们提供一个SQL查询,并调用前面定义的函数来提取表名和视图名。然后,我们可以根据需要进一步处理和呈现结果。

def main():
    sql_query = "SELECT IDENTITY(INT,1,1) AS id, * INTO #dbw_temp FROM [DBWComplexFunction].[dbo].[slow_sql_record] WHERE starttime = getdate()"
    if len(sql_query) > 10000:
        sql_query = sql_query[:10000]
    
    parsed_sql = format_sql(sql_query)
    table_names = extract_table_names(parsed_sql)
    
    # 更多自定义处理,例如表名去重
    
    # 输出结果
    if not table_names:
        table_names = 'NULL'
    else:
        table_names = ','.join(table_names)
    
    print("物理表:{}".format(table_names))
    
if __name__ == "__main__":
    main()

table_names1输出的是符合条件的所有物理表名和视图名的集合,这里需要自己写一个对照程序,用于对照那些是视图那些是物理表

EASY~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值