需要获取tablename从输入使用SQL查询.我知道这可以通过regex完成,但不知道如何因此任何帮助赞赏 输入:

Field1 field2
a INSERT INTO test.table2{ name, age, city, id}SELECT name, age, city, id FROM table 1
b select from test1.table3
c select *from test2.table4
d select *from test2.table4(10)

输出:

Field1 field2
a test.table2
b test1.table3
c test2.table4

推荐答案

这将是非常困难的仅使用正则表达式.如果你真的需要做reliably,你可以根据他们的需要做check out how pgpool-II re-used PostgreSQL's own parser—这是一个C++密集型任务,而不是SQL任务.

Here are some more examples at the wiki,其中一些可以直接使用.您甚至可以让Python sqlparse处理查询文本,然后处理.get_identifiers(),所有这些都在db中,在一个PL/Python函数中.

如果你只想涵盖一些非常基本的情况,你可以try 将目标标记放在某些关键字下面:

select field1
  ,unnest(
      regexp_matches(
         field2
        ,'(?:UPDATE|INTO|FROM|JOIN|USING|TABLE)(?:\s+ONLY)*\s+([[:alpha:]_]+[[:word:]]*|"[^"]+")'
        ,'gi'
      )
   ) AS spotted_table
from table1;
field1 spotted_table
a table2
a table1
b table3
c table4
  • ?: in (?:something)使括号不可捕获,这就是为什么它只报告来自最后一组没有?:的匹配项
  • 'gi'中的g使此报告全部匹配,i禁用区分大小写
  • the identifier syntax is taken from the doc, except the $ oddity:

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

这个关键字列表绝不是详尽无遗的,虽然它涵盖了示例,但这个正则表达式非常脆弱.看obvious blind spots in this demo个左右.

如果你考虑到

  • 标识符可以是双引号,也可以是非引号,这使它们成为fold to lowercase.
  • 包含SQL外观文本的单个或美元引号字符串常量—如果您也考虑dynamic SQL,则非常有用,否则它会导致错误肯定
  • 从技术上讲,你可以把一个表命名为"select from table7 join TABLE8 on waitaminute;"(整个表就是表的名称,而不仅仅是table7部分):demo
  • 长的、逗号分隔的关系列表与非关系的源交织,特别是子查询
  • 行尾//和行内/多行/*...*/条 comments

如果您正在分析的查询在您保存它们的同一个数据库上运行,则可以将其与information_schema.tables相关联.注意,在查询主体中,有9 different things可以在同一个位置,这还不包括table只是其中一种形式的relation.你也可以从viewmaterialized viewforeign tablepartitioned table中 Select select,所有这些都在某种程度上像table.Some views are updatable,这意味着您也可以从它们insert/merge/update/delete,就像您直接与它们的底层表交互一样.

如果你试图跟踪有效的交互,你还必须跟踪ruletrigger系统、视图和matview定义以及routine主体和依赖项.

Postgresql相关问答推荐

Postgres SQL执行加入

端口5432失败:致命:数据库xxx&不存在.在PostgreSQL数据库中

PostgreSQL plpgsql函数问题

为MCV扩展统计设置统计目标

为什么Postgres优化器切换到嵌套循环进行连接?

使用 pgAdmin 4 v7.4 在 Windows 11 上全新安装 PostgreSQL 15.3-3 无法启动 - 卡在正在加载 pgAdmin 4 v7.4...

当参数大小超过 393166 个字符时,PSQL 准备语句查询挂起

使用 select 在带有特殊字符的字符串中查找数据

GORM 不会创建 many2many 关联

!= 和 <> 运算符有什么区别?

将 PostgreSQL 配置为仅适用于 LOCALHOST 或指定的 ip + 端口

如何确定 NULL 是否包含在 Postgres 的数组中?

从time without time zone和时区名称中获取time with time zone

仅当 PostgreSQL 表不存在时才添加主键

在 PostgreSQL 中将列数据类型从 Text 更改为 Integer

是否可以在 CSV 格式的 Postgres COPY 命令中关闭报价处理?

当从 Heroku pg:pull 数据库时提示:role "root" does not exist.

Ecto Postgres 安装错误密码验证失败

postgresql DB中唯一键的正确数据类型是什么?

JOIN (SELECT ... ) ue ON 1=1?