使用正则表达式获取表名称

问题描述 投票:0回答:1

需要使用sql查询从输入中获取表名。我知道这可以通过正则表达式来完成,但不确定如何因此感谢任何帮助 输入:

字段1 字段2
a 插入 test.table2{ 姓名、年龄、城市、id}从表 1 中选择姓名、年龄、城市、id
b 从test1.table3中选择
c 从 test2.table4 中选择*
d 从test2.table4(10)中选择*

输出:

字段1 字段2
a 测试.表2
b 测试1.表3
c 测试2.表4
postgresql postgresql-9.1 postgresql-9.3 postgresql-9.5
1个回答
0
投票

仅用正则表达式是很难实现的。如果您确实需要可靠地这样做,您可以查看如何

pgpool-II
重新使用 PostgreSQL 自己的解析器来满足他们的需求 - 这更多是一项 C++ 密集型任务,而不是 SQL 任务。

如果您只想涵盖一些非常基本的情况,您可以尝试按照某些关键字来定位标记:

select field1
  ,unnest(
      regexp_matches(
         field2
        ,'(?:UPDATE|INTO|FROM|JOIN|USING|TABLE)(?:\s+ONLY)*\s+([[:alpha:]_]+[[:word:]]*|"[^"]+")'
        ,'gi'
      )
   ) AS spotted_table
from table1;
字段1 spotted_table
a 表2
a 表1
b 表3
c 表4
  • ?:
    中的
    (?:something)
    使括号无法捕获,这就是为什么它只报告最后一组没有
    ?:
  • 的匹配项
  • g
    中的
    'gi'
    使此报告全部匹配,并且
    i
    禁用区分大小写
  • 标识符语法取自文档,除了
    $
    奇怪之处:

    SQL 标识符和关键字必须以字母(

    a-z
    ,也可以是带有变音符号的字母和非拉丁字母)或下划线(
    _
    )开头。标识符或关键字中的后续字符可以是字母、下划线、数字 (
    0-9
    ) 或美元符号 (
    $
    )

该关键字列表绝不是详尽无遗的,虽然它涵盖了您的示例,但这个正则表达式非常脆弱。请参阅此演示中的一些明显盲点

如果你考虑的话,事情会变得越来越棘手

  • 标识符可以用双引号或不带引号,这使得它们折叠为小写
  • 包含 SQL 外观文本的单引号或美元引号字符串常量 - 如果您还考虑动态 SQL,则很有用,否则它会给您带来误报
  • 从技术上讲,你可以命名一个表
    "select from table7 join TABLE8 on waitaminute;"
    (这整个就是表的名称,而不仅仅是
    table7
    部分):demo
  • 以逗号分隔的长关系列表,与非关系的源交错,尤其是子查询
  • 行尾
    //
    和内嵌/多行
    /*...*/
    注释

如果您正在分析的查询在您保存它们的同一个数据库上运行,您可以将其与

information_schema.tables
相关联。请注意,查询正文中的同一位置可以有 9 种不同的事物,这还不包括 table 只是其中一种形式(关系)的事实。您还可以从
select
view
materialized view
foreign table
变为
partitioned table
,所有这些都在某种程度上类似于
table
某些视图是可更新的,这意味着您还可以从它们中
insert
/
merge
/
update
/
delete
,就像直接与它们的基础表进行交互一样。

如果您想跟踪有效的交互,则还必须跟踪

rule
trigger
系统、视图和 matview 定义以及
routine
主体和依赖项。

© www.soinside.com 2019 - 2024. All rights reserved.