Extrahieren Sie den Tabellennamen mit SQL aus einer Spalte, in der Abfragen gespeichert sind

Dec 09 2020

In einer Tabelle werden Abfragen gespeichert, und ich muss den Tabellennamen aus diesen Abfragen extrahieren.

Tabelle: Haupt

ICH WÜRDE Abfragetext
1 Wählen Sie a.record_id, a.name, b.person FROM database.atable aus. a join database.btable b on b.id = a.id;
2 Wählen Sie c.record_id, c.name, d.person FROM database.ctable aus. c join database.dtable d on c.id = d.id;

Erwartete Ergebnisse:

database.atable
database.ctable

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

Das funktioniert fast, aber ich weiß nicht, wie lang oder kurz der Tabellenname sein könnte. Wenn es länger als 30 ist, werden die Ergebnisse abgeschnitten. Wenn es kürzer ist, kann es andere Teile der Abfrage enthalten. Ich las strtok und dachte darüber nach, damit in den Raum nach dem Namen zu gelangen, um anzuhalten, konnte es aber nicht ganz zum Laufen bringen.

Antworten

2 esqew Dec 09 2020 at 02:18

Scheint so, als wäre dies ein guter Anwendungsfall für REGEXP_SUBSTR:

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

Das Muster sucht nach dem Zeichenfolgenliteral FROM database., das unmittelbar vor einem Tabellennamen steht, der dem Muster entspricht (.+?\b).

Weiter - das Muster (.+?\b)stimmt mit allen Zeichen ( .) überein, die mindestens einmal ( +) nicht gierig ( ?Token) vorkommen, bis zu einem Wortbegrenzungszeichen ( \b), das nach Ihren Beispieldaten auf dem Leerzeichen übereinstimmen sollte, das unmittelbar vor dem Tabellennamen steht.

Mit einem Dienstprogramm wie Regex101 können Sie sehen, wie dieses Muster noch detaillierter interpretiert wird .


Weitere (wenn auch leicht tangentiale) Informationen zur RegExp-Unterstützung im PCRE-Stil in Teradata: Regex-Syntax in Teradata

access_granted Dec 09 2020 at 02:49

Wenig funky aussehend, sollte aber funktionieren:

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;

oder in deinem Fall

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