客户场景:mysql数据库,字段值都是查询语句,例如:select * from info _resource_site_img limit 100; 如何获取字段值中的表名? 方法一:使用正则表达式(MySQL 8.0+)1. 具体公式: REGEXP_REPLACE( REGEXP_SUBSTR( query_column, 'FROM[[:space:]]+([`"\\[\\]\\w._-]+)', 1,-- 从第1个字符开始匹配 1,-- 匹配第1个结果 'i'-- 忽略大小写 ), '[`"\\[\\]]', -- 清理特殊字符 '' ) 2. 正则表达式详解 'FROM[[:space:]]+([`"\\[\\]\\w._-]+)': FROM:匹配 FROM 关键字。 [[:space:]]+:匹配任意空白(包括空格、换行符)。 表名匹配规则: 支持反引号 `、双引号 "、方括号 [] 包裹的表名。 允许普通表名(含字母、数字、下划线 _、点 .、连字符 -)。 捕获组 ():提取表名部分。 3. 清理特殊字符 REGEXP_REPLACE(..., '[`"\\[\\]]', ''):移除表名中的引号或方括号。 方法二:字符串函数(兼容所有版本)1. 具体公式: TRIM( BOTH '`' FROM SUBSTRING_INDEX( SUBSTRING_INDEX( SUBSTRING(query_column, INSTR(LOWER(query_column), 'from') + 4), -- 截取FROM后的内容 ' ', 1 -- 取第一个空格前的片段 ), '`', -1 -- 移除反引号(如果有) ) ) 2. 逻辑说明 SUBSTRING(query_column, INSTR(...) + 4):截取 FROM 之后的内容。 SUBSTRING_INDEX(..., ' ', 1):提取第一个空格前的字符串。 TRIM(BOTH '' FROM ...)`:清理表名两侧的反引号。 案例测试:输入数据
输出结果
问题与改进:最后一个示例错误提取了 (SELECT,改进方案: REGEXP_SUBSTR(query_column, 'FROM[[:space:]]+((?!\\()[^\\s,)+)', 1, 1, 'i') 最终建议:简单场景:使用方法一(正则表达式),需确保 MySQL 版本 ≥ 8.0。 复杂查询:结合代码(如 Python 的 sqlparse 库)解析 SQL 语法树。 低版本 MySQL:使用方法二(字符串函数),但需处理更多边缘情况。 注意事项:不支持提取 JOIN 多表或子查询中的表名。 表名含特殊字符(如空格)时需调整正则或字符串截取逻辑。 |