mboost-dp1
C# Regex til at finde SQL-queries
- Forside
- ⟨
- Forum
- ⟨
- Programmering
Jeg forsøger at lede kildekoden til en Stored Procedure igennem og trække alle SQL-queries ud af denne. Jeg er dog ikke interesseret i det, der står efter WHERE-delen, da jeg kun skal bruge navnet på de tabeller der refereres til.
Problemet er denne del:
(where|end|if|else|select|delete|update)
Grunden til at bruge det er, at det er de måder man kan finde afslutningen på en query - Problemet er bare at hvis en query afsluttes fordi en ny select startes så får man ikke den næste select med, da den jo var en del af den første match.
Nogen der kan hjælpe mig eller henvise mig til en bedre løsning?
Regex r = new Regex("select(.+?)from(.+?)(where|end|if|else|select|delete|update)", RegexOptions.IgnoreCase);
Match = r.Match(str_source);
Problemet er denne del:
(where|end|if|else|select|delete|update)
Grunden til at bruge det er, at det er de måder man kan finde afslutningen på en query - Problemet er bare at hvis en query afsluttes fordi en ny select startes så får man ikke den næste select med, da den jo var en del af den første match.
Nogen der kan hjælpe mig eller henvise mig til en bedre løsning?
#1
Du kunne starte med at splitte op i sætninger (adskilt af semikolon) og processe dem en ad gangen.
Derudover skal du nok have lidt mere for at finde tabelnavnene udfra FROM expression, der jo både kan være old style og nye JOIN style.
Og så er der spørgsmålet om hvordan du vil håndtere diverse subquery syntaxer.
Du kunne starte med at splitte op i sætninger (adskilt af semikolon) og processe dem en ad gangen.
Derudover skal du nok have lidt mere for at finde tabelnavnene udfra FROM expression, der jo både kan være old style og nye JOIN style.
Og så er der spørgsmålet om hvordan du vil håndtere diverse subquery syntaxer.
#4
Som sagt er det bare en start.
Hvis du læser mit oprindelige spørgsmål vil du se at jeg spørger om, hvordan jeg får den næste select med (da den jo også afslutter den forrige).
I mellemtiden har jeg dog fundet ud af at man kan trække alle SQL-queries ud af en stored procedure ved hjælp af dens execution plan. Så det løser da en lille del af mit problem...
Som sagt er det bare en start.
Hvis du læser mit oprindelige spørgsmål vil du se at jeg spørger om, hvordan jeg får den næste select med (da den jo også afslutter den forrige).
I mellemtiden har jeg dog fundet ud af at man kan trække alle SQL-queries ud af en stored procedure ved hjælp af dens execution plan. Så det løser da en lille del af mit problem...
#9
I så fald ville jeg nok kigge på at køre samtlige stored procedures (måske på en klon af database strukturen / virtuel maskine), og så aflæse hvilke tabeller der er blevet kørt kode på via. en profiler.
Har du prøvet med SQL Query Analyzer?
http://msdn.microsoft.com/en-us/library/aa216945(S...
I så fald ville jeg nok kigge på at køre samtlige stored procedures (måske på en klon af database strukturen / virtuel maskine), og så aflæse hvilke tabeller der er blevet kørt kode på via. en profiler.
Har du prøvet med SQL Query Analyzer?
http://msdn.microsoft.com/en-us/library/aa216945(S...
Ud over, at jeg har kildekoder til alle SP'er har jeg dog også en database med bla. alle SP'erne i. Dette er dog en prokuktions-database, så jeg kan ikke rigtig afvikle dem.
Til gengæld kan jeg afvikle følgende kode og få execution plan for en vilkårlig SP.
Så kan jeg få navne på berørte tabeller og returneret samtlige queries i SP'en.
Så jeg skal egentlig bare kunne trække tabel-navne ud af en vilkårlig query (både select, delete og update).
Til gengæld kan jeg afvikle følgende kode og få execution plan for en vilkårlig SP.
set showplan_xml on
GO
exec min_sp
Så kan jeg få navne på berørte tabeller og returneret samtlige queries i SP'en.
Så jeg skal egentlig bare kunne trække tabel-navne ud af en vilkårlig query (både select, delete og update).
#1: Nu skal jeg ikke kunne sige hvor let det er at bruge en SQL grammatik og parser generator, hvis det er nemt så er det selvfølgelig oplagt.
Men ellers tror jeg sådanset ikke at den her opgave kræver en fullblown parser, mit gæt er at man ville kunne løse det her med en simpel state parser der følger de grundlæggende regler for statement-opbygnig i SQL, men drop regex det giver dig kun problemer her. Pointen er at du kun skal bruge 5% af en fullblown SQL parser og det gør det faktisk realitisk at skrive den del selv på et par timer.
Men ellers tror jeg sådanset ikke at den her opgave kræver en fullblown parser, mit gæt er at man ville kunne løse det her med en simpel state parser der følger de grundlæggende regler for statement-opbygnig i SQL, men drop regex det giver dig kun problemer her. Pointen er at du kun skal bruge 5% af en fullblown SQL parser og det gør det faktisk realitisk at skrive den del selv på et par timer.
#22
Prøv:
Prøv:
using System;
using System.Text.RegularExpressions;
namespace E
{
public class Program
{
public static void Test(string re1, string s1)
{
Regex re = new Regex(re1);
Match m = re.Match(s1);
Console.WriteLine(re1 + " " + s1 + " : " + m.Success + (m.Success ? (" " + m.Value) : ""));
}
public static void Main(string[] args)
{
string[] re = { "x.+y", "x.+?y", "x.?y", "x.*y" };
string[] s = { "xy", "x1y", "x12y", "x1yx2y" };
foreach(string re1 in re)
{
foreach(string s1 in s)
{
Test(re1,s1);
}
}
Console.ReadKey();
}
}
}
Tak for de mange svar!
Hvis jeg må have lov til at vende tilbage til mit originale spørgsmål.
slutningen" på mit regex-pattern (slutningen kunne evt. være ordet "select"), bliver jo en del af den næste query i SP'en.
Det betyder jo så at den næste query IKKE kommer med i min regex-match...
Hvordan klarer jeg det?
Hvis jeg må have lov til at vende tilbage til mit originale spørgsmål.
slutningen" på mit regex-pattern (slutningen kunne evt. være ordet "select"), bliver jo en del af den næste query i SP'en.
Det betyder jo så at den næste query IKKE kommer med i min regex-match...
Hvordan klarer jeg det?
#26
I den angivne regex i #1 betyder ? non-greedy uanset eksempel eller ej.
Er forkert.
Fordi en SP kan indeholde mere end en query og fordi der kan optræde sub select i where delen, så er non-greedy absolut nødvendigt til dette formål.
I den angivne regex i #1 betyder ? non-greedy uanset eksempel eller ej.
gnarfsan (22) skrev:Han matcher jo også 0 tegn, når han har ? med.
Er forkert.
Fordi en SP kan indeholde mere end en query og fordi der kan optræde sub select i where delen, så er non-greedy absolut nødvendigt til dette formål.
Gå til top
Opret dig som bruger i dag
Det er gratis, og du binder dig ikke til noget.
Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.