Dans ce cas, la situation est un peu différente car les mots à conserver ne sont pas définis, par contre ils sont repérables car toujours situés après l'instruction FROM(*) et éventuellement séparés par des virgules quand il y en a plusieurs. Contrairement au cas précédent, les FROM table1 ne peuvent pas se succéder, il est donc inutile de répéter le groupe contenant FROM et les noms de table. Aussi vu que l'on sait à quel type de chaîne on a à faire, on peut être un peu plus explicite avec les classes de caractères utilisées.
On peut décrire le nom d'une table comme une suite de caractères n'ayant ni espaces, ni virgules, ni point-virgules: [^ ;,]+
Donc un ou plusieurs noms de table séparés par des virgules: [^ ;,]+( *, *[^ ;,]+)*
On capture l'ensemble de ces noms de table et on place un FROM devant: FROM +([^ ;,]+( *, *[^ ;,]+)*)
Reste donc a construire l'expression avec ces éléments comme précédemment:
( +FROM( ) *([^ ;,]+( *, *[^ ;,]+)*) *;?)? *[^ ]+( +FROM +([^ ;,]+( *, *[^ ;,]+)*)[ ;]*$)?
À noter la ruse pour récupérer un espace dans le groupe 2 juste après le premier FROM pour en disposer quand on en a besoin. Malheureusement même de cette manière, il n'est pas possible d'éviter tous les espaces inutiles.
Ce qui donne:
regexp_replace(upper(Le_Text), '( +FROM( ) *([^ ;,]+( *, *[^ ;,]+)*) *;?)? *[^ ]+( +FROM +([^ ;,]+( *, *[^ ;,]+)*)[ ;]*$)?', '\3\2\6')
(*) On part du principe que FROM est toujours suivi d'un ou plusieurs noms de tables et que la chaîne ne contient que des requêtes basiques. Ce n'est pas forcément le cas, par exemple FROM pourrait être suivi d'un nom d'utilisateur ou de rôle lors d'une modification de privilèges ou encore de la pseudo table DUAL lors d'un calcul. Autre chose, un nom de table peut très bien être suivi d'une définition d'alias: FROM table1 AS toto, table2 t2. L'expression précédente ne gère pas ces cas et, à vrai dire, les gérer n'est plus du ressort des expressions régulières mais d'une analyse syntaxique du langage SQL.
Partager