【问题标题】:Extract table name using SQL from a column that stores queries使用 SQL 从存储查询的列中提取表名
【发布时间】:2021-03-20 03:35:21
【问题描述】:

一个表在其中存储查询,我需要从这些查询中提取表名。

表:主

ID querytext
1 select a.record_id, a.name, b.person FROM database.atable a join database.btable b on b.id= a.id;
2 select c.record_id, c.name, d.person FROM database.ctable c join database.dtable d on c.id= d.id;

预期结果:

database.atable
database.ctable

SELECT SUBSTR(querytext, position('database.' in querytext), 30) FROM main;

这几乎可以工作,但我不知道表名可以多长或多短。如果超过 30,则会截断结果。如果更短,它可以包括查询的其他部分。我正在阅读 strtok 并考虑使用它来到达名称后的空格以停止,但无法使其正常工作。

【问题讨论】:

    标签: sql teradata


    【解决方案1】:

    似乎这可能是REGEXP_SUBSTR 的一个很好的用例:

    SELECT REGEXP_SUBSTR(querytext, '(<?FROM database\.)(.+?\b)', 1, 1, 'i')
    

    该模式查找紧接在与模式(.+?\b) 匹配的表名之前的字符串文字FROM database.

    进一步 - 模式 (.+?\b) 匹配任何字符 (.) 至少出现一次 (+) 非贪婪 (? 令牌) 直到单词边界字符 (\b),它从您的示例数据来看,应该与表名后面的空格匹配。

    您可以使用Regex101 之类的实用程序更详细地了解此模式的解释方式。


    关于 Teradata 中 PCRE 样式的 RegExp 支持的进一步(尽管有点切题)阅读:Regex syntax in teradata

    【讨论】:

    • 这是一个很好的答案。 +1 链接到 Regex101 它允许我调整一些东西。
    【解决方案2】:

    看起来有点时髦,但应该可以:

    select 
      strtok( substr( strsql, index(strsql,'FROM ')+length('FROM '), length(strsql)), ' ', 1 ) 
    from (
    select 
    'select c.record_id, c.name, d.person FROM database.ctable c join database.dtable d on c.id= d.id' 
      as strsql
    ) s1;
    

    或者在你的情况下

    select strtok( 
      substr( querytext, index(querytext,'FROM ')+length('FROM '), length(querytext)) 
      ,' ', 1 
      ) from main;
    

    【讨论】:

      猜你喜欢
      • 2023-02-25
      • 2016-06-08
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多