(This is a C# LinqPad script)
Finds the SQL Command Variable definitions in a SQL script and parses their names and values.
Finds the SQL Command Variable references and parses their names.
Determines which references have no definitions.
Determines which definitions have no references.
The definition names and reference names are case insensitive.
A definition is in the form of :setvar name “value”
A reference is in the form of $(name)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
void Main() { //sql file path string file = @"C:\temp\my.sql"; //Token definition pattern for :setvar name "value" string tokenDefPattern = @"(\:setvar [^""]* ""[^""]*"")"; string tokenDefNamePattern = @"\:setvar ([^ ""]*)"; string tokenDefValuePattern = @"""([^""]*)"""; //Token reference pattern for $(name) string tokenRefPattern = @"(\$\([^)]*\))"; string tokenRefNamePattern = @"\$\(([^)]*)\)"; string text = System.IO.File.ReadAllText(file); var tokenDefs = Token.GetAllFirstCapturedMatches(text,tokenDefPattern).Distinct().ToDictionary(x=>x,y=>new Token(y,tokenDefNamePattern,tokenDefValuePattern)); var tokenRefs = Token.GetAllFirstCapturedMatches(text,tokenRefPattern).Distinct().ToDictionary(x=>x,y=>new Token(y,tokenRefNamePattern,null)); tokenDefs.Select(x=>x.Value).OrderBy (x => x.Name).ToList().Dump("Token Definitions"); tokenDefs.Where(x=> !tokenRefs.Any(y => y.Value.Name == x.Value.Name)).Select(x=>x.Value).OrderBy(x => x.Name).ToList().Dump("Token definitions without a reference"); tokenRefs.Where(x=> !tokenDefs.Any(y => y.Value.Name == x.Value.Name)).Select(x=>x.Value).OrderBy(x => x.Name).ToList().Dump("Token references without a definition"); } public class Token { public Token(){} public Token(string Raw, string namePattern, string valuePattern) { this.Raw = Raw; if(!string.IsNullOrWhiteSpace(namePattern)) Name = Token.GetFirstCapturedMatch(Raw,namePattern); if(!string.IsNullOrWhiteSpace(valuePattern)) Value = Token.GetFirstCapturedMatch(Raw,valuePattern); } public string Name {get;set;} public string Value {get;set;} public string Raw {get;set;} public static string GetFirstCapturedMatch(string value, string pattern) { var match = Regex.Match(value,pattern); if(match!=null && match.Success && match.Groups.Count>1) { return match.Groups[1].Value; } return null; } public static List<string> GetAllFirstCapturedMatches(string value, string pattern) { var list = new List<string>(); var matches = Regex.Matches(value,pattern); foreach(Match match in matches) { if(match!=null && match.Success && match.Groups.Count>1) { list.Add(match.Groups[1].Value); } } return list; } } |