Extraire le nom de la table à l'aide de SQL à partir d'une colonne qui stocke les requêtes

Dec 09 2020

Une table y stocke des requêtes et je dois extraire le nom de la table de ces requêtes.

table: principale

identifiant texte de requête
1 sélectionnez a.record_id, a.name, b.person FROM database.atable a join database.btable b on b.id = a.id;
2 sélectionnez c.record_id, c.name, d.person FROM database.ctable c join database.dtable d sur c.id = d.id;

Résultats attendus:

database.atable
database.ctable

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

Cela fonctionne presque, mais je ne sais pas combien de temps le nom de la table pourrait être. S'il est supérieur à 30, les résultats seront coupés. S'il est plus court, il peut inclure d'autres parties de la requête. Je lisais strtok et j'ai pensé à l'utiliser pour accéder à l'espace après le nom pour arrêter, mais je ne pouvais pas tout à fait le faire fonctionner.

Réponses

2 esqew Dec 09 2020 at 02:18

On dirait que cela pourrait être un bon cas d'utilisation pour REGEXP_SUBSTR:

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

Le modèle recherche le littéral de chaîne FROM database.qui précède immédiatement un nom de table correspondant au modèle (.+?\b).

De plus, le modèle (.+?\b)correspond à tous les caractères ( .) apparaissant au moins une fois ( +) non avidement ( ?jeton) jusqu'à un caractère de limite de mot ( \b), qui, à en juger par vos exemples de données, devrait correspondre sur l'espace blanc précédant immédiatement le nom de la table.

Vous pouvez voir comment ce modèle est interprété de manière encore plus détaillée à l'aide d'un utilitaire tel que Regex101 .


Lectures supplémentaires (quoique légèrement tangentielles) concernant le support RegExp de style PCRE dans Teradata: syntaxe Regex dans teradata

access_granted Dec 09 2020 at 02:49

Peu d'apparence géniale, mais devrait fonctionner:

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;

ou dans votre cas

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