7
votes

Utilisation de Regex pour extraire les noms de table à partir d'un fichier contenant des requêtes SQL

J'ai un fichier texte contenant un grand nombre de requêtes. Je veux obtenir toutes les tables distinctes utilisées dans l'ensemble du fichier dans toutes les requêtes. Le nom de la table peut venir après un «de» ou «rejoindre». Comment puis-je les extraire en faisant une correspondance de regex. Quelqu'un peut-il suggérer une expression régulière pour obtenir les matchs?


0 commentaires

6 Réponses :


-1
votes
(from|join)\s(\w+)

2 commentaires

Non. Cela correspondra simplement à "de" ou "Rejoindre Table_Name", mais pas "de Nom de table". Le tuyau divise tout le motif, pas seulement la première partie.


Hmm. Alors puis-je envelopper de | rejoindre avec des parenthèses ou quelque chose?



1
votes

Quelque chose comme ça peut-être: XXX

Il ne correspondra pas aux noms de table évasés, et vous devez faire de l'évaluation de la regex-insensible.


4 commentaires

Pardon. Il ne renvoie même pas un match.


absolument faux. Vous ne pouvez pas trouver de noms de table avec une telle regex. Vous allez faire correspondre les mots rejoindre et depuis aussi. Non seulement les noms de table.


Je ne l'ai pas testé, mais cela devrait correspondre à chaque apparition de «de» ou de «jointure», suivie d'au moins un espace, puis un ou plusieurs identifiants séparés avec des points. Il y a une erreur cependant; Il devrait commencer par une affirmation de départ, sinon elle correspondra également à des choses comme foobarfrom bla . Et il ne faut pas s'échapper en compte, car c'est une chose spécifique à la SGMS - MySQL utilise des backuotes, PostgreSQL utilise des guillemets doubles, T-SQL utilise des crochets.


Oh, et évidemment, les regexnes ne sont pas un moyen fiable de le faire de toute façon. Si vous voulez fiable, vous avez besoin d'un analyseur SQL complet.



6
votes

J'utiliserais: xxx pré>

une fois que vous avez l'objet correspondant "M", vous aurez le nom de la table avec P>

string line = @"select * from tb_name join tb_name2 ON a=b WHERE x=y";
Regex r = new Regex(@"(from|join)\s+(?<table>\S+)",
         RegexOptions.IgnoreCase|RegexOptions.Compiled);

Match m = r.Match(line);
while (m.Success) {
   Console.WriteLine (m.Groups["table"].Value);
   m = m.NextMatch();
}


0 commentaires

7
votes

Cela dépend de la structure de votre fichier. Essayez d'utiliser ceci:

(?<=from|join)(\s+\w+\b)


7 commentaires

Je pense que vous devez déplacer le \ S + dans la veille positive


-1 regex n'est pas le moyen correct de résoudre ce problème. En tant que TDAMMERS SES, un analyseur SQL de certaines description est nécessaire pour résoudre efficacement ce problème.


@El Ronnoco J'ai demandé une solution à l'aide de Regex et il l'a donc fourni. Je veux juste une solution rapide et sale pour cela et je l'ai eu.


Pour le schéma de support, j'ajoute peu de symbole: (? <= De | rejoindre) (\ S + \ w + \. + \ W + \ b)


Je pense que ça ne va pas fonctionner s'il y a une sélection commentée dans votre chaîne.


En fait, il y a quelques cas de bord sur les fonctions de chaîne: Dev.MYSQL .COM / DOC / REFMAN / 5.7 / FR / String-Fonctions.HTML substrat, sous-chaîne et garniture peut spécifier certains paramètres à partir du mot clé, qui n'a rien à voir avec des tables


Vous devez ajouter que cela ne fonctionnerait pas pour insérer une déclaration



0
votes

peut essayer ceci, mais cela ne fonctionne pas pour tous les types de requêtes,

  public void Main()
    {
        // TODO: Add your code here

        string Line = string.Empty;

        using (StreamReader sr = new StreamReader(@"D:\ssis\queryfile.txt"))//reading the filename
        {

            var text = string.Empty;

            do
            {
                //     MessageBox.Show(Line);
                text = Line = sr.ReadToEnd();// storing it in a variable by reading till end

                MessageBox.Show(Line);



            } while ((Line = sr.ReadLine()) != null);



            var text1 = text.Replace("[", string.Empty).Replace("]", string.Empty);//replacing brackets with empty space

            MessageBox.Show(text1);



            Regex r = new Regex(@"(?<=from|join)\s+(?<table>\S+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);//regex for extracting the tablename after from and join

            Match m = r.Match(text1);//creating match object

            MessageBox.Show(m.Groups[1].Value);

            var v = string.Empty;



            while (m.Success)
            {

                v = m.Groups[0].Value;

                m = m.NextMatch();


                StreamWriter wr = new StreamWriter(@"D:\ssis\writefile.txt", true);// writing the match to the file

                var text2 = v.Replace(".", " ,"); // replace the . with , seperated values


                wr.WriteLine(text2);

                sr.Close();
                wr.Close();

            }
        }
    }


0 commentaires

0
votes

Solutions qui peuvent vous aider.

1. Extrayez les noms de table avec alias d'une instruction SQL avec regex h5>

expression régulière p> xxx pré>

2. Extrayez les noms de table d'une instruction SQL avec regex h5>

expression régulière p> xxx pré>

chaîne de test p> xxx pré>

Code généré pour c # p> xxx pré>

comment l'utiliser. P> xxx pré>

sortie p> xxx Pré>

extrait les noms de colonne d'une instruction SQL avec regex h5>

expression régulière p> xxx pré>

chaîne de test p> xxx Pré>

Code généré pour C # P> xxx pré>

Comment utiliser p> xxx pré>

sortie p>

[a].[column_1]
`b`.`column_2`
c.column_3
column_4
`column_5`
[column_6]
column_7
column_8
column_9


1 commentaires

Je cherchais des idées pour moi-même, mais je ne les ai pas trouvées comme prévu, je dois donc laisser quelque chose. J'espère que ça vous plait.