Verborgener Schatz: Microsoft.SqlServer.SqlParser.dll
Hast Du schon man Dein Systemlaufwerk danach durchsucht, wie viele & welche DLL (Dynamic Linked Library) es so gibt?
Wenn nicht: Lass es, es gibt sprichwörtlich unendliche viele davon.
Findet man dann eine vom Namen her interessante DLL und sucht dann danach im Internet, bekommt man nicht unbedingt immer die gewünschten Infos oder gar eine umfassende Dokumentation dazu.
Das wiederum ist echt schade, denn einige dieser DLL bieten sehr interessante und gut brauchbare Funktionen; würde man die kennen, müsste man so einiges nicht selbst programmieren; wirklich echte verborgene Schätze, die da brach liegen.
Über einen dieser kleinen Schätze bin ich gestolpert und der hat durchaus interessante Funktionen und sich daraus ergebene Möglichkeiten.
Es ist die Microsoft.SqlServer.SqlParser.dll, die eine komplette SQL Parser Funktionalität biete. Man übergibt ein SQL Statement oder gar ganze SQL Batches und die Klasse „Parser“ analysiert es, gibt als Ergebnis die gefundenen Fehler und, was wesentlich interessanter ist, splittet die einzelne Teile des SQL Statements in einzelne Tokens auf. Diese kann man dann selbst weiter auswerten.
Hier der Visual Basic.NET 2008 Source Code als kleine Demo (Konsolen-Anwendung) dazu, dass das SQL Statement in meinem Sinne etwas besser automatisiert formatiert:
Module SqlParserTest ''' <summary> ''' Demo zu Microsoft.SqlServer.SqlParser.dll als Konsolen-Applikation ''' </summary> ''' <remarks>Olaf Helper, 08.08.2009 ''' Verweis setzen auf: ''' C:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Microsoft.SqlServer.SqlParser.dll ''' </remarks> Sub Main() Dim sql As String Dim script As Microsoft.SqlServer.SqlParser.SqlCodeDom.SqlScript Dim stringBuilder As New System.Text.StringBuilder Dim token As Microsoft.SqlServer.SqlParser.Parser.Token
sql = "-- Erstes Statement völlig Valide, aber mies formatiert " & vbNewLine & _ "select [AddressID] " & _ ", [AddressLine1] " & _ ",[AddressLine2] " & _ ", [City] " & _ "fRoM [AdventureWorks].[Person].[Address] " & _ "whERe PostalCode = '98011';" & vbNewLine & _ "GO;" & vbNewLine & _ "-- Zweites Statement: So strunz fehlerhaft " & vbNewLine & _ "-- das es schon weh tut; Format auch nicht besser " & vbNewLine & _ "select * " & _ "FRoM TabelleA oder TabelleB " & _ "where Ja = Vielleicht <> Nein;" script = Microsoft.SqlServer.SqlParser.Parser.Parser.Parse(sql) System.Console.WriteLine("Anzahl Batches: " & script.Batches.Count.ToString) System.Console.WriteLine("Anzahl Fehler: " & script.Errors.Count.ToString)
For Each token In script.Tokens Select Case token.Id Case 40, 41, 59, 61 'Separatoren wie ()=; die dürfen ohne Spaces sein stringBuilder.Append(token.Text.Trim) Case 42, 171 'Felder; die nur trimmen stringBuilder.Append(token.Text.Trim) Case 44, 498 'Leerbereich; hier nur max. ein Space stringBuilder.Append(token.Text.Trim & " ") Case 242, 287, 307 'SQL Klauseln wie SELECT FROM WHERE 'Die als UPPER in nächster Zeile stringBuilder.Append(vbNewLine & token.Text.ToUpper(System.Globalization.CultureInfo.CurrentCulture)) Case 499 'Kommentare; in neue Zeile & keine unnötigen Spaces stringBuilder.Append(vbNewLine & token.Text.Trim.Replace(" ", " ")) Case 501
'Batchtrenner GO; immer in neuer Zeile
stringBuilder.Append(vbNewLine & token.Text.Trim)
Case Else
'Alles andere unverändert zurückgeben
stringBuilder.Append(token.Text)
End Select Next
System.Console.WriteLine(stringBuilder.ToString)
System.Console.WriteLine("Press key to continue")
System.Console.ReadLine()
End Sub
End Module
Und das Ergebnis ist:
-- Erstes Statement völlig Valide, aber mies formatiert
SELECT [AddressID] , [AddressLine1] , [AddressLine2] , [City]
FROM [AdventureWorks].[Person].[Address]
WHERE PostalCode = '98011';
GO;
-- Zweites Statement: So strunz fehlerhaft
-- das es schon weh tut; Format auch nicht besser
SELECT *
FROM TabelleA oder TabelleB WHERE Ja = Vielleicht <> Nein;
Der als solche auch erkannte SQL Bug ist immer noch drin, aber es ist schon durch diese einfache kleine Routine wesentlich besser formatiert. Verbesserungspotential gibt es wie immer auch hier.
Mmmh, das ist doch einen nette Funktionalität für ein SSMS Addin. ;-)
Wenn ich nur mehr Zeit hätte …