Home > SQL-Server 2005 > T-SQL: Kommentare aus Scripts entfernen

T-SQL: Kommentare aus Scripts entfernen

Um eine Datenbank nach Objekten zu durchsuchen die einen vorgegebenen String enthalten muss man nur durch die System-View sys.sql_modules parsen. Hier steht im Feld “Definitions” der Quelltext von Funktionen, Prozeduren oder Views.

 T-SQL |  copy code |? 
1
SELECT OBJECT_ID,definition FROM sys.sql_modules WHERE definition like '%[^a-zA-Z0-9_]Contact[^a-zA-Z0-9_]%'
2

Allerdings hat dieses einfache Verfahren einen Nachteil. Wenn der Quellcode sehr gut dokumentiert ist bzw. durch andere Vorgaben viele Kommentarbereiche enthalten sind, kann das Ergebnis eine ganze Menge an Treffern anzeigen die man so vielleicht gar nicht haben wollte.

Um also diese Kommentare aus den Quelltexten (weitestgehend) zu entfernen, habe ich eine scalar Funktion geschrieben die dies bei einer Abfrage direkt erledigen kann. Der Rest des Quellcodes kann man dann nach dem gewünschten Begriff durchsuchen und erhält so hoffentlich eine aussagekräftigere Ergebnismenge.

Hier das Script:

 T-SQL |  copy code |? 
001
002
CREATE FUNCTION dbo.[SVF_StripComments](@Textfeld NVARCHAR(MAX))
003
RETURNS NVARCHAR(MAX)
004
AS
005
BEGIN
006
    /* --------------------------------------------------------
007
       Die Funktion entfernt Kommentare aus einem gegebenen String
008
       Es werden Zeilenkommentare als auch Blockkommentare
009
       entfernt. Die Zeilenschaltung bei Zeilenkommentaren bleibt
010
       erhalten.
011
 
012
       Es werden auch Kommentare in Strings ersetzt. Dies bedeutet
013
       bei Zeilenkommentaren, dass hier das Ende mit dem Ende
014
       des Strings erreicht wird.
015
      --------------------------------------------------------- */
016
 
017
    DECLARE @DefLen		INT
018
    DECLARE @InString	BIT
019
    DECLARE @I			INT
020
    DECLARE @Mask		TINYINT
021
    DECLARE @MoveCursor INT
022
    DECLARE @TempSpace	NVARCHAR(MAX)
023
 
024
    DECLARE @IsLineCmt  BIT
025
    DECLARE @IsBlockCmt TINYINT
026
 
027
    SET @TempSpace = ''
028
    SET @DefLen    = LEN(@Textfeld)
029
    SET @I         = 1
030
    SET @Mask      = 0
031
    SET @InString  = 0
032
    SET @IsLineCmt = 0
033
    SET @IsBlockCmt= 0
034
    SET @MoveCursor= 1
035
 
036
    -- Quellstring zeichenweise durchlaufen
037
 
038
    WHILE @I <= @DefLen
039
    BEGIN
040
 
041
        -- Beim Zeilenkommentar innerhalb eines Strings ist
042
        -- das Ende des Kommentars, wenn das Ende des Strings
043
        -- erreicht ist.
044
        -- Wenn noch ein Blockkommentar vorhanden ist, dann
045
        -- noch nicht die @Mask-Variable (Kommentarkennzeichen)
046
        -- zurücksetzen da wir ja noch im Kommentar sind.
047
 
048
        IF @IsLineCmt = 1 and @InString = 1 and SUBSTRING(@Textfeld,@I,1) = ''''
049
        BEGIN
050
            SET @IsLineCmt	= 0
051
            SET @Mask       = CASE WHEN @IsBlockCmt > 0 THEN 1 ELSE 0 END
052
        END
053
 
054
        -- Stringtest (befinden wir uns in einem String?)
055
        -- Dies ist nur außerhalb eines Kommentars notwendig ..
056
 
057
        IF @IsLineCmt = 0 and @Mask = 0 and SUBSTRING(@Textfeld,@I,1) = ''''
058
        BEGIN
059
            SET @InString = CASE @InString WHEN 1 THEN 0 ELSE 1 END
060
        END
061
 
062
        -- ----------------------------------------------------------------------------
063
        -- Beginn der Kommentare testen
064
        -- ----------------------------------------------------------------------------
065
 
066
        -- Begin eines Block-Kommentars?
067
 
068
        IF SUBSTRING(@Textfeld,@I,2) = '/*' and @IsLineCmt = 0
069
        BEGIN
070
            SET @Mask       = 1
071
            SET @IsBlockCmt = @IsBlockCmt + 1
072
        END
073
 
074
        -- Begin eines Zeilenkommentars?
075
        -- Innerhalb eines Kommentars wird nicht geprüft!
076
 
077
        IF @Mask = 0 and SUBSTRING(@Textfeld,@I,2) = '--'
078
        BEGIN
079
            SET @Mask      = 1
080
            SET @IsLineCmt = 1
081
        END
082
 
083
        -- ----------------------------------------------------------------------------
084
        -- Auf Ende der Kommentare testen
085
        -- ----------------------------------------------------------------------------
086
 
087
        -- Ende der Zeile beim Zeilenkommentar?
088
 
089
        IF @IsLineCmt = 1 and SUBSTRING(@Textfeld,@I,2) = CHAR(13)+CHAR(10)
090
        BEGIN
091
            SET @Mask = 0
092
        END
093
 
094
        -- Ende der Zeile beim Block-Kommentar?
095
 
096
        IF @IsBlockCmt > 0 and SUBSTRING(@Textfeld,@I,2) = '*/'
097
        BEGIN
098
            SET @I = @I + CASE WHEN @IsBlockCmt > 1 THEN 1 ELSE 2 END
099
 
100
            SET @IsBlockCmt = @IsBlockCmt - 1
101
 
102
            IF @IsBlockCmt <= 0
103
            BEGIN
104
                SET @IsBlockCmt = 0
105
                SET @Mask       = 0
106
                SET @MoveCursor = 0
107
            END
108
        END
109
 
110
        -- ----------------------------------------------------------------------------
111
        -- Bei CRLF bzw. Block-Ende werden zwei Zeichen ersetzt.
112
        -- Wenn dies der Fall ist, dann darf bei der Mask-Abfrage der "Cursor" im
113
        -- Quellstring nicht mehr weiter gerechnet werden.
114
        -- ----------------------------------------------------------------------------
115
 
116
        -- Wenn der Zeilenkommentar (mit CRLF) endet ...
117
 
118
        IF @IsLineCmt = 1 and @Mask = 0
119
        BEGIN
120
            SET @TempSpace = @TempSpace + SUBSTRING(@Textfeld,@I,2)
121
            SET @IsLineCmt = 0
122
 
123
            SET @I = @I + 2
124
            SET @MoveCursor = 0
125
 
126
            -- innerhalb eines Blockkommentars?
127
            SET @Mask = CASE @IsBlockCmt WHEN 1 THEN 1 ELSE 0 END
128
        END
129
 
130
        -- ----------------------------------------------------------------------------
131
        -- Wenn @Mask gesetzt ist, dann Inhalt der Quelle ignorieren
132
        -- im anderen Fall wird der Inhalt in den Arbeitsbereich kopiert.
133
        -- ----------------------------------------------------------------------------
134
 
135
        IF @Mask = 1
136
        BEGIN
137
            SET @I = @I + 1
138
        END
139
 
140
        -- Wenn @MoveCursor = 0 ist, dann wurde der Spaltenzähler bereits auf das
141
        -- nächste zu verarbeitende Zeichen gesetzt.
142
        -- Es muss dann keine weitere Verarbeitung durchgeführt werden.
143
 
144
        IF @MoveCursor = 0
145
        BEGIN
146
            SET @MoveCursor = 1
147
        END
148
        ELSE
149
        BEGIN
150
            IF @Mask = 0
151
            BEGIN
152
                SET @TempSpace = @TempSpace + SUBSTRING(@Textfeld,@I,1)
153
                SET @I = @I + 1
154
            END
155
        END
156
    END
157
 
158
    RETURN @TempSpace
159
END
160
go
161
 
162
-- --------------------------------------------------------------
163
-- ... und hier die Funktion testen
164
-- --------------------------------------------------------------
165
 
166
DECLARE @Textfeld NVARCHAR(1000);
167
 
168
SET @Textfeld = '
169
-- -----------------------------
170
-- Hello World
171
-- -----------------------------
172
// Hello World
173
Hello ''''''World'''' -- Hier ist ein Kommentar'' + Nachlauf
174
/* Hello ''''''World'''' -- Hier ist ein Kommentar'' + Nachlauf
175
   Hier gehts weiter mit World */ wie auch immer
176
 -> Achtung: ''und noch eine World.Tabelle''
177
 ->          hier ist endlich Schluss mit World_usw.
178
 
179
/*
180
Hier -- ''Kommentar
181
sein oder nichtsein.
182
*/
183
';
184
 
185
PRINT '========================================================='
186
PRINT dbo.SVF_StripComments(@Textfeld)
187
PRINT '========================================================='
188

have fun

8-)

KategorienSQL-Server 2005
  1. Bisher keine Kommentare
  1. Bisher keine Trackbacks