[..] Analyseur de requêtes SQL et expressions régluières

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
scorp84
Niveau 7
Niveau 7
Messages : 365
Enregistré le : mar. 04 nov. 2008 21:51
Status : Hors ligne

[..] Analyseur de requêtes SQL et expressions régluières

#1

Message par scorp84 » ven. 27 sept. 2019 14:35

Bonjour à tous,

Je suis en train (d'essayer :-) d'écrire un analyseur de requêtes SQL.

Mon besoin est d'extraire les nom des champs et des tables pour vérifier si l'orthographe est correcte.

Mais ils peuvent être dans le select, le left join, le where, le group by, le order by, ... et le nom des tables peuvent ne pas y être.

J'ai commencé à y travailler pour le select et voici ce que ça donne :
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=..\..\..\Autoit - Icones_encrypted\Porte documents.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <Array.au3>
#include <SQL.au3>
#Include <String.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>

; DESCRIPTIF SCRIPT
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
$script_titre="ANALYSEUR SQL"
$script_desc="Analyseur de requêtes SQL"
$auteur="BM"
$maj="27/09/19" ; MES : 20/09/19
$ver="1.01"
$nom_fenetre_gui=$script_titre & " - v." & $ver
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


; GUI PRINCIPALE
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#Region ### START Koda GUI section ### Form=x:\dropbox\developpement\autoit - bm'tools_encrypted\developpement\analyseur requêtes sql\analyseur sql 1.kxf
Global $Form1 = GUICreate($nom_fenetre_gui, 1174, 466, -1, -1)
Global $Group_sql = GUICtrlCreateGroup(" REQUETE ", 8, 8, 601, 233)
Global $Edit_sql = GUICtrlCreateEdit("", 16, 24, 585, 209,$ES_AUTOVSCROLL + $WS_VSCROLL + $ES_MULTILINE + $ES_WANTRETURN)
GUICtrlCreateGroup("", -99, -99, 1, 1)
Global $Btn_analyse = GUICtrlCreateButton("Analyse", 528, 248, 75, 25)
Global $Group_resultat = GUICtrlCreateGroup(" RESULTAT ", 8, 280, 601, 177)
Global $ListView_resultat = GUICtrlCreateListView("", 16, 296, 586, 150)
GUICtrlCreateGroup("", -99, -99, 1, 1)
Global $Group_analyse = GUICtrlCreateGroup(" ANALYSE REQUETE ", 616, 8, 545, 449)
Global $Edit_pb = GUICtrlCreateEdit("", 624, 24, 521, 425)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

; A mettre après Edits
; $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_MULTILINE + $ES_WANTRETURN)

; Récup noms des tables et des champs
$sql="select TABLE_NAME,COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS " & _
"ORDER BY TABLE_NAME,COLUMN_NAME"
Global $tab_tables_et_champs=f_220_bdd2($sql)

;_ArrayDisplay($tab_tables_et_champs)

; EXEMPLES DE REQUÊTES
$sql="SELECT TOP 1 CLIENT.CLIENT_CODE,CLIENT.PRESTAT_CODE AS TEST,CLIENT.FOURN_CODE,CLIENT.DO_CODE,ST_CODE,RTRIM(CLIENT_NOM) AS CLIENT_NOM,RTRIM(PRESTAT_ID) AS PRESTAT_ID,RTRIM(FOURN_ID) AS FOURN_ID,RTRIM(DO.DO_ID) AS DO_ID,RTRIM(CLIENT_NUM) AS CLIENT_NUM,CLIENT_RESILIE " & _
"FROM SRV WITH(NOLOCK) " & @CRLF & _
"LEFT JOIN DO WITH(NOLOCK) ON SERVICE.DO_CODE=DO.DO_CODE " & _
"LEFT JOIN FOURN ON SERVICE.FOURN_CODE=FOURN.FOURN_CODE " & _
"LEFT JOIN PRESTAT ON SERVICE.PRESTAT_CODE=SI.PRESTAT_CODE " & _
"LEFT JOIN CLI WITH(NOLOCK) ON SERVICE.CLIENT_CODE=CLIENT.CLIENT_CODE " & _
"WHERE SERVICE.SERVICE_CODE='3327811'"

; Si utilsiation exemple, affichage requête
GUICtrlSetData($Edit_sql,$sql)


; Boucle dans GUI
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit

         Case $Btn_analyse

                 f_analyse_sql(GUICtrlRead($Edit_sql))
 EndSwitch
WEnd
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX



; FONCTION : ANALYSE SQL
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Func f_analyse_sql($sql)

        ; Ajoute retour à la ligne
        $sql=StringReplace($sql,@CRLF,"")
        $sql=StringReplace($sql,"FROM ", @CRLF & "FROM ")
        $sql=StringReplace($sql,"LEFT JOIN ", @CRLF & "LEFT JOIN ")
        $sql=StringReplace($sql,"WHERE ", @CRLF & "WHERE ")
        $sql=StringReplace($sql,"AND ", @CRLF & "AND ")

        ; réaffiche la requête
        GUICtrlSetData($Edit_sql,$sql)

        ; Vide les problèmes
        GUICtrlSetData($Edit_pb,"")

        ; Passe requête en majuscules
        $sql=StringUpper($sql)

        ; Supprime les retours chartiots pour analyse
        $sql=StringReplace($sql,@CRLF,"")

        ; >>> ANALYSE PARTIE SELECT
        ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        If StringLeft($sql,6)="SELECT" Then

                ; Position du FROM
                $from_pos=StringInStr($sql,"FROM ")

                ; FROM manquant
                If $from_pos=0 Then
                        GUICtrlSetData($Edit_pb,"'FROM' manquant ou mal orthographié")
                EndIf

                ; Position du WITH(NOLOCK)
                $with_no_lock_pos=StringInStr($sql,"WITH(NOlOCK)")

                ; WITH(NOLOCK) manquant
                If $with_no_lock_pos=0 Then
                        GUICtrlSetData($Edit_pb,GUICtrlRead($Edit_pb) & "'WITH(NOLOCK)' manquant ou mal orthographié" & @CRLF)
                EndIf

                ; Nom table principale
                $nom_table_from=StringMidBornes($sql,$from_pos+5,$with_no_lock_pos-2)

                ; Vérif table from
                f_verif_table($nom_table_from)

                ; Récup SELECT
                $select=_ArrayToString(StringRegExp($sql, "SELECT (.*) FROM", 3), "")
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $select = ' & $select & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

                ; Supprime TOP si existe
                If StringLeft($select,3)="TOP" Then
                        $top_2eme_espace=StringInStr($select," ",0,2)

                        $top=StringMidBornes($select,1,$top_2eme_espace)

                        $select=StringMid($select,$top_2eme_espace+1)
                EndIf

                ; PB AS
                StringReplace($select," AS "," ")
                $as_nb=@extended

                If $as_nb>0 Then
                        GUICtrlSetData($Edit_pb,GUICtrlRead($Edit_pb) & "Pour renommer les champs, il ne faut plus utiliser 'AS'. Vous l'avez fait " & $as_nb & " fois" & @CRLF)
                EndIf

                ; CHAMPS SELECT

                $tab_champs=StringReplace($select," ",",")
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $tab_champs = ' & $tab_champs & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
                $tab_champs=StringSplit($select,",")

                ;_ArrayDisplay($tab_champs)

                ; Boucle dans les champs
                For $i=1 to UBound($tab_champs)-1

                        ; Récup champ
                        $champ_en_cours=$tab_champs[$i]

                        ; Supp RTRIM(
                        $champ_en_cours=StringReplace($champ_en_cours,"RTRIM(","")

                        ; Supp )
                        $champ_en_cours=StringReplace($champ_en_cours,")","")

                        ; Récup position 1er espace
                        $pos_espace=StringInStr($champ_en_cours," ")

                        ; Si espace, ne conserve que ce qui est avant
                        If $pos_espace>0 then $champ_en_cours=StringLeft($champ_en_cours,$pos_espace-1)

                        If $champ_en_cours<>"*" then f_verif_champ($champ_en_cours)

                Next

                ; ANALYSE JOINTURES LEFT JOIN
                $left_join=StringRegExp($sql, "LEFT JOIN .* ON .*=.*\s", 3)

                _ArrayDisplay($left_join)
        EndIf
        ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

        If GUICtrlRead($Edit_pb)="" Then GUICtrlSetData($Edit_pb,"Pas d'erreur détectée")
EndFunc
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


; FONCTION : BDD 192.168.0.220 / bdd                                              03/05/16
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Func f_220_bdd2($254_bdd_sql)

;~ #include <Array.au3>
;~ #include <SQL.au3>
;~ #Include <String.au3>

        $oADODB = _SQL_Startup()

        ; Arrêt si erreur SQL
        If $oADODB = $SQL_ERROR then
                MsgBox(262144+16,"SQL","Erreur connexion SQL")
                Return
        EndIf

        ; Mot de passe crypté
        $mdp_crypte=_StringEncrypt(0,"XXX","YYYY",2)

        ; Connexion SQL
        If _sql_Connect(-1,"192.168.0.122","bdd","bdd",$mdp_crypte) = $SQL_ERROR then
                _SQL_Close()
                Return 0
        EndIf

        ; Test si requête SELECT
        If StringLeft($254_bdd_sql,6)="SELECT" Then

                ; Execute requête SELECT
                Local $aData,$iRows,$iColumns
                $sql_query = _SQL_GetTable2D(-1,$254_bdd_sql,$aData,$iRows,$iColumns) ; ATTENTION LIGNE 0 A SUPPRIMER CAR DOUBLON

                _SQL_Close()

                Return $aData
        Else
                ; Execute requête INSERT, UPDATE, DELETE
                _SQL_Execute(-1,$254_bdd_sql)

                _SQL_Close()

                Return 1
        EndIf

EndFunc
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Func StringMidBornes($SMB_chaine,$SMB_debut,$SMB_fin)
        Return StringMid($SMB_chaine,$SMB_debut,$SMB_fin-$SMB_debut+1)
EndFunc
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Func f_verif_table($table)

        ; Recherche nom table
        $table_id=_ArraySearch($tab_tables_et_champs, $table,0,0,0,0,1,0) ; Recherche exacte dans colonne 0

        ; Msg si nom base incorrect
        If $table_id=-1 Then
                GUICtrlSetData($Edit_pb,GUICtrlRead($Edit_pb) & "'" & $table & "' n'est pas un nom de table correct" & @CRLF)
        EndIf

EndFunc
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Func f_verif_champ($champ)

        ; Récup position point
        $pos_point=StringInStr($champ,".")
        ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $pos_point = ' & $pos_point & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

        ; Si point, séparation table et champ
        If $pos_point>0 Then

                ; Récup table
                $table_en_cours=StringLeft($champ,$pos_point-1)
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $table_en_cours = ' & $table_en_cours & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

                ; Vérif table
                f_verif_table($table_en_cours)

                ; Récup champ
                $champ=StringMid($champ,$pos_point+1)
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $champ = ' & $champ & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

                ; Recherches toutes occurences champ
                $tab_champ_dans_tables=_ArrayFindAll($tab_tables_et_champs,$champ,Default,Default,Default,0,1) ; Correspondance exacte dans la colonne 1

                $table_champ_ok=0

                ; Boucle dans liste pour trouver si table+champ OK
                For $i=0 to UBound($tab_champ_dans_tables)-1

                        If $tab_tables_et_champs[$tab_champ_dans_tables[$i]][0]=$table_en_cours then
                                $table_champ_ok=1
                                ExitLoop
                        EndIf
                Next

                ; Erreur correspondance champ et table
                If $table_champ_ok=0 Then
                        GUICtrlSetData($Edit_pb,GUICtrlRead($Edit_pb) & "'" & $champ & "' n'existe pas dans la table '" & $table_en_cours & "'" & @CRLF)
                EndIf

        Else

                ; Si pas de nom de table

                ; Récup champ
                $champ=StringMid($champ,$pos_point+1)
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $champ = ' & $champ & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

                ; Recherche nom table
                $champ_id=_ArraySearch($tab_tables_et_champs, $champ,0,0,0,0,1,1) ; Recherche exacte dans colonne 1

                ; Msg si nom champ incorrect
                If $champ_id=-1 Then
                        GUICtrlSetData($Edit_pb,GUICtrlRead($Edit_pb) & "'" & $champ & "' n'est pas un nom de champ correct" & @CRLF)
                EndIf
        EndIf

EndFunc
; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Les Dieux des expressions régulières auraient-ils une formule magique pour avoir NOM_TABLE.NOM_CHAMP dans un tableau ou est-ce que j'en demande un peu trop et que je doive analyser bloc par bloc ?

Si c'est la cas, est-il possible d'extraire les nom de champs et de tables de cette expression :
LEFT JOIN DO WITH(NOLOCK) ON SERVICE.DO_CODE=DO.DO_CODE
LEFT JOIN FOURN ON SERVICE.FOURN_CODE=FOURN.FOURN_CODE
LEFT JOIN PRESTAT ON SERVICE.PRESTAT_CODE=SI.PRESTAT_CODE

...Sachant que le nombre de LEFT JOIN (ou INNER JOIN) n'est pas limité.

J'ai tenté ça :
LEFT JOIN(.*) WITH\(NOLOCK\) ON (.*)=(.*)

Mais je ne sais pas lui dire que tout le bloc peut-être 0 ou n fois.

Ou alors, exclure tous les mots pouvant être dans une requête (Select, where, left join, ...) et prendre le reste ?

Merci d'avance pour vos conseils.

Amicalement.

BM

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2094
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Analyseur de requêtes SQL et expressions régluières

#2

Message par jchd » ven. 27 sept. 2019 20:36

C'est une très grosse entreprise ! Même si on se cantonne à une seule version d'un seul moteur SQL, c'est chaud.

Voir par exemple ceci : http://jakewheat.github.io/simple-sql-parser/latest/
et quelques exemples de production : http://jakewheat.github.io/simple-sql-p ... cases.html

Bon ce truc est en Haskell ce qui montre que la barre est haute, du seul fait des vastes possibilités de ce langage de haut niveau, mais on soupçonne vite que la tâche globale est du genre brutal.

La grammaire SQL est complexe et fortement récursive à tous les étages, quelque soit le moteur considéré.

Si je devais m'impliquer dans un truc pareil (ce que je ne ferai certainement pas), je découperai en morceaux de niveau 1, en recursant sur chaque morceau jusqu'à plus soif. Comme ça on construit l'abre de la requête petit à petit.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

Avatar du membre
scorp84
Niveau 7
Niveau 7
Messages : 365
Enregistré le : mar. 04 nov. 2008 21:51
Status : Hors ligne

Re: [..] Analyseur de requêtes SQL et expressions régluières

#3

Message par scorp84 » lun. 30 sept. 2019 10:29

Bonjour Jchd,

Merci pour vos conseils :-)

Grâce à vos liens, je prends la mesure de la complexité de l'entreprise...

Je vais essayer de me cantonner dans un premier temps à extraire uniquement les noms de champs et de tables.
; EXEMPLES DE REQUÊTES
$sql="SELECT TOP 1 CLIENT.CLIENT_CODE,CLIENT.PRESTAT_CODE TEST,CLIENT.FOURN_CODE,CLIENT.DO_CODE,ST_CODE,RTRIM(CLIENT_NOM) CLIENT_NOM,RTRIM(PRESTAT_ID) PRESTAT_ID,RTRIM(FOURN_ID) FOURN_ID,RTRIM(DO.DO_ID) DO_ID,RTRIM(CLIENT_NUM) CLIENT_NUM,CLIENT_RESILIE " & _
"FROM SRV WITH(NOLOCK) " & @CRLF & _
"LEFT JOIN DO WITH(NOLOCK) ON SERVICE.DO_CODE=DO.DO_CODE " & _
"LEFT JOIN FOURN ON SERVICE.FOURN_CODE=FOURN.FOURN_CODE " & _
"LEFT JOIN PRESTAT ON SERVICE.PRESTAT_CODE=SI.PRESTAT_CODE " & _
"LEFT JOIN CLI WITH(NOLOCK) ON SERVICE.CLIENT_CODE=CLIENT.CLIENT_CODE " & _
"WHERE SERVICE.SERVICE_CODE='3327811'"
Si je reprends ma requête, et que je supprime tous les mots clés courants (select, from, on, ...) et que je supprime les RTRIM(), serait-il possible avec les regexp d'extraire :
  • Tout ce qui est après un espace une virgule ou après un =
  • Tout ce qui est avant un point, une virgule ou un =

Cela me donnerait une liste du genre :
CLIENT.CLIENT_CODE
PRESTAT_ID
SRV
SERVICE.FOURN_CODE

Je n'aurai plus alors qu'à séparer la table et le champ s'il y a un point et de chercher dans la liste des champs ou des tables pour valider.

L'idéal serait que j'arrive en fonction de la position (après un from, c'est forcément une table par exemple, après un where ou un and, j'ai forcément au minimum un champ) à définir si c'est une table ou un champ.

Oh, Dieux des Regexp, mon vœu est-il exhaussable ? :lol:

Merci d'avance pour vos conseils.

Amicalement.

BM

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2094
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Analyseur de requêtes SQL et expressions régluières

#4

Message par jchd » mar. 01 oct. 2019 02:37

Code : Tout sélectionner

with recursive blah (v1, v2,v3) as (
values ...
union all
select ...,
select
col1,
col2,
(select sum(that) from t1 natural join t2 where condition group by something) "Mon total",
v2
from a1, blah, a2 on conditions compliquées
where plein de choses
Et on recurse les select autant qu'il faut à droite à gauche, et on ajoute une bonne fonction de "windowing" et toute "feature" qu'offre tel ou tel RDBMS, incompatible avec le RDBMS d'à côté.

Franchement pas si simple, du seul fait de la complexité potentielle de la moindre requête du monde réel.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

Avatar du membre
scorp84
Niveau 7
Niveau 7
Messages : 365
Enregistré le : mar. 04 nov. 2008 21:51
Status : Hors ligne

Re: [..] Analyseur de requêtes SQL et expressions régluières

#5

Message par scorp84 » mar. 01 oct. 2019 10:21

Bonjour JCHD,

Effectivement la complexité des requêtes est quasi-infinie.

Par contre, les types de requêtes que je fais sont relativement "formatées". Je vais perdre en universalité mais je cherche surtout à détecter les nom des champs et les noms des tables pour détecter des erreurs de saisie.

Voici où j'en suis :
; EXEMPLES DE REQUÊTES
$sql="SELECT TOP 1 CLI.CLI_CODE,CLI.SI_CODE AS TEST,CLI.TLS_CODE,CLI.PRES_CODE,ST_CODE,RTRIM(CLI_NOM) AS CLI_NOM,RTRIM(SI_ID) AS SI_ID,RTRIM(TLS_ID) AS TLS_ID,RTRIM(PRES.PRES_ID) AS PRES_ID,RTRIM(CLI_NUM) AS CLI_NUM,CLI_RESILIE " & _
"FROM SRV WITH(NOLOCK) " & @CRLF & _
"LEFT JOIN PRES WITH(NOLOCK) ON SRV.PRES_CODE=PRES.PRES_CODE " & _
"LEFT JOIN TLS ON SRV.TLS_CODE=TLS.TLS_CODE " & _
"LEFT JOIN SI ON SRV.SI_CODE=SI.SI_CODE " & _
"LEFT JOIN CLI WITH(NOLOCK) ON SRV.CLI_CODE=CLI.CLI_CODE " & _
"WHERE SRV.SRV_CODE='3327811'"

f_analyse_sql($sql)

Func f_analyse_sql($sql)

        $tab_a_suppr=@CRLF & ",SELECT,FROM, LEFT JOIN,RTRIM(,TOP,ON,WITH(NOLOCK),WHERE)"
        $tab_a_suppr=StringSplit($tab_a_suppr,",")

        For $i=1 to UBound($tab_a_suppr)-1

                $sql=StringReplace($sql,$tab_a_suppr[$i],"")
        Next

        $sql=StringReplace($sql,"="," ")
        $sql=StringReplace($sql,","," ")

        GUICtrlSetData($Edit_pb,$sql)

        $sql=StringSplit($sql," ")

        _ArrayDisplay($sql)


EndFunc

J'essaye les regexp mais je n'y suis pas encore...

$tmp=StringRegExp($sql, "[ |,]([^\)]*)[ |,]", 3)
_ArrayDisplay($tmp)
Amicalement.

BM

Répondre