【问题标题】:Parse table names from a bunch SQL statements从一堆 SQL 语句中解析表名
【发布时间】:2012-11-02 04:44:57
【问题描述】:

我有一个表,在名为 Queries 的列中包含数千条 SQL 语句。关于如何使用正则表达式从语句中获取表名的任何想法?

【问题讨论】:

  • @Fake.It.Til.U.Make.你是隐瞒答案还是只是评论?
  • 为了获得更接近或更准确的响应,您需要提供更多详细信息。有什么例子吗?还是您面临的问题?
  • 如果你想从一个 select 语句中执行它,你应该在其中创建一个 SQL 解析器,使用 regex 或 wahtever。例如,您将不得不解析表引用和连接。
  • 只有正则表达式?可能不可能,尤其是当 Oracle 允许 CTE(内联视图声明)时。我可能会将包含您的查询的表just粘贴到一个新的数据库实例中,然后告诉它全部执行,从错误消息中解析出表名(字符串中的标准位置!) - 并创建它们,显然,因为语句通常包含多个表。
  • 这些陈述是否具有可预测的模式?例如,表名是否总是以“FROM”或“JOIN”开头?我知道并非所有可能的查询都如此,但您知道您的查询是否属实吗?

标签: python sql regex linux oracle


【解决方案1】:

如果是我,我会倾向于尝试以不同的方式解决问题。我倾向于为每个对象生成一个查询计划,而不是编写一个 SQL 解析器(这将需要比正则表达式更多的东西,除非你可以保证所有 SQL 语句都使用可用 SQL 语法的一个非常小的子集)。查询 PLAN_TABLE 以查看 Oracle 必须命中的对象。您需要对索引访问进行额外查找,以找出索引是在哪个表上定义的,但这应该相当简单。

但是,如果您走这条路,您将检索查询实际涉及的基表,而不是查询可能实际引用的任何视图。也就是说,如果您有一个查询SELECT * FROM view_1view_1,反过来又被定义为针对table_atable_b 的查询,那么只有table_atable_b 将是计划的一部分。如果您想要阻止查询计划引用具体化视图(如果这些具体化视图不是查询的特定部分),则您需要为会话禁用 query_rewrite

如果,对于每个查询,你做一个

EXPLAIN PLAN FOR <<the query>>

你就可以了

SELECT DISTINCT object_owner, object_name, object_type
  FROM plan_table

获取对象列表。如果OBJECT_TYPEINDEX% 类似,则可以使用DBA_INDEXES 视图(或ALL_INDEXESUSER_INDEXES,具体取决于谁拥有相关对象以及您拥有的权限级别)来确定索引的表定义于

SELECT table_owner, table_name
  FROM dba_indexes
 WHERE owner = <<object_owner from plan_table>>
   AND index_name = <<object_name from plan_table>>

所以,例如,如果我有一个视图view_1

 create or replace view view_1
 as
 select *
   from emp join dept using (deptno)

还有一个查询

select * from view_1;

我可以的

SQL> explain plan for select * from view_1;

Explained.

SQL> ed
Wrote file afiedt.buf

  1      SELECT distinct object_owner, object_name, object_type
  2*       FROM plan_table
SQL> /

OBJECT_OWNER                   OBJECT_NAME               OBJECT_TYPE
------------------------------ ------------------------- -------------------------

SCOTT                          DEPT                      TABLE
SCOTT                          PK_DEPT                   INDEX (UNIQUE)
SCOTT                          EMP                       TABLE

这告诉我查询实际上是命中EMPDEPT 表。它还达到了PK_DEPT 索引,因此我可以查看定义的表。

SQL> ed
Wrote file afiedt.buf

  1      SELECT table_owner, table_name
  2        FROM dba_indexes
  3       WHERE owner = 'SCOTT'
  4*        AND index_name = 'PK_DEPT'
SQL> /

TABLE_OWNER                    TABLE_NAME
------------------------------ ------------------------------
SCOTT                          DEPT

事实证明,该索引也在DEPT 表上定义,所以我知道只有SCOTT 模式中的EMPDEPT 表将参与查询。

【讨论】:

  • 听起来不错。但我不是甲骨文的人。您能否推荐我应该使用的 PLAN_TABLE 查询以及如何使用?谢谢!
  • @user836087 - 更新了一个例子。
  • @justin-cave 请注意,对涉及其他模式的查询执行解释计划可能会遇到权限问题 - 但我一直在尽可能地这样做。否则,我有一个经常遇到问题的 pyparsing 解析器。维护是一个非常令人头疼的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
相关资源
最近更新 更多