2017-07-02 76 views
0

使用SMO和ASP.NET,我試圖將突出顯示和行格式添加到SMO對象(表,視圖等)的腳本方法。目前,我正在使用String.Replace方法來匹配關鍵字,但似乎沒有捕獲所有關鍵字。我在數組中有關鍵字,然後循環直到匹配TSQL腳本。我不確定需要匹配的字符才能獲取所有關鍵字並獲得類似於SQL Manager的行格式。格式化TSQL字符串以使用ASP.NET模仿SQL管理器的最佳方式是什麼?

Dim searchArr As Array = {"ADD", "EXTERNAL", "PROCEDURE", "ALL", "FETCH", "PUBLIC", "ALTER", "FILE", "RAISERROR", "AND", "FILLFACTOR", "READ", "ANY", "FOR", "READTEXT", "AS", "FOREIGN", "RECONFIGURE", 
       "ASC", "FREETEXT", "REFERENCES", "AUTHORIZATION", "FREETEXTTABLE", "REPLICATION", "BACKUP", "FROM", "RESTORE", "BEGIN", "FULL", "RESTRICT", "BETWEEN", "FUNCTION", "RETURN", 
       "BREAK", "GOTO", "REVERT", "BROWSE", "GRANT", "REVOKE", "BULK", "GROUP", "RIGHT", "BY", "HAVING", "ROLLBACK", "CASCADE", "HOLDLOCK", "ROWCOUNT", "CASE", "IDENTITY", "ROWGUIDCOL", 
       "CHECK", "IDENTITY_INSERT", "RULE", "CHECKPOINT", "IDENTITYCOL", "SAVE", "CLOSE", "IF", "SCHEMA", "CLUSTERED", "IN", "SECURITYAUDIT", "COALESCE", "INDEX", "SELECT", 
       "COLLATE", "INNER", "SEMANTICKEYPHRASETABLE", "COLUMN", "INSERT", "SEMANTICSIMILARITYDETAILSTABLE", "COMMIT", "INTERSECT", "SEMANTICSIMILARITYTABLE", 
       "COMPUTE", "INTO", "SESSION_USER", "CONSTRAINT", "IS", "SET", "CONTAINS", "JOIN", "SETUSER", "CONTAINSTABLE", "KEY", "SHUTDOWN", "CONTINUE", "KILL", "SOME", 
       "CONVERT", "LEFT", "STATISTICS", "CREATE", "LIKE", "SYSTEM_USER", "CROSS", "LINENO", "TABLE", "CURRENT", "LOAD", "TABLESAMPLE", "CURRENT_DATE", "MERGE", "TEXTSIZE", 
       "CURRENT_TIME", "NATIONAL", "THEN", "CURRENT_TIMESTAMP", "NOCHECK", "TO", "CURRENT_USER", "NONCLUSTERED", "TOP", "CURSOR", "NOT", "TRAN", "DATABASE", "NULL", "TRANSACTION", 
       "DBCC", "NULLIF", "TRIGGER", "DEALLOCATE", "OF", "TRUNCATE", "DECLARE", "OFF", "TRY_CONVERT", "DEFAULT", "OFFSETS", "TSEQUAL", "DELETE", "ON", "UNION", "DENY", "OPEN", "UNIQUE", 
       "DESC", "OPENDATASOURCE", "UNPIVOT", "DISK", "OPENQUERY", "UPDATE", "DISTINCT", "OPENROWSET", "UPDATETEXT", "DISTRIBUTED", "OPENXML", "USE", "DOUBLE", "OPTION", "USER", 
       "DROP", "Or", "VALUES", "DUMP", "ORDER", "VARYING", "ELSE", "OUTER", "VIEW", "END", "OVER", "WAITFOR", "ERRLVL", "PERCENT", "WHEN", "ESCAPE", "PIVOT", "WHERE", "EXCEPT", "PLAN", "WHILE", 
       "EXEC", "PRECISION", "WITH", "EXECUTE", "PRIMARY", "WITHIN GROUP", "EXISTS", "PRINT", "WRITETEXT", "EXIT", "PROC", "CREATE PROCEDURE", "NOCOUNT", "COUNT"} 
Dim srv As Server 
Dim name As String 
Dim db As Database 
Dim sp As StoredProcedure 

Private Sub Admin_Props_Load(sender As Object, e As EventArgs) Handles Me.Load 
    openDB() 
    db = srv.Databases(databaseName) 
    If Len(Request.QueryString("name")) = 0 Then 
     lblData.Text = "Not a valid StoredProcedure" 
    Else 
     sp = db.StoredProcedures(Request.QueryString("name").ToString) 
     lblData.Text = addHighlight(sp.TextBody) 
    End If 
End Sub 
Sub openDB() 
    Dim sqlConn As New SqlConnection("Data Source=xxxx;Integrated Security=True;") 
    Dim SerCon As New Microsoft.SqlServer.Management.Common.ServerConnection(sqlConn) 
    srv = New Server(SerCon) 
End Sub 

Function addHighlight(ByVal strIn As String) As String 

    Dim keyWords As Array = searchArr 
    Dim keyInd As Integer 
    Dim str2() As String 
    str2 = strIn.Split(" ") 
    If Len(Trim(strIn)) > 0 And IsArray(keyWords) Then 
     For keyInd = LBound(keyWords) To UBound(keyWords) 
      For i As Integer = LBound(str2) To UBound(str2) 
       str2(i) = Replace(str2(i), UCase(keyWords(keyInd)), "*|*" & UCase(keyWords(keyInd)) & "*||*", 1, -1, 1) 
       'strIn = Replace(strIn, UCase(keyWords(keyInd)), "*|*" & UCase(keyWords(keyInd)) & "*||*", 1, -1, 1) 
      Next 
     Next 
    End If 
    strIn = Join(str2, " ") 
    strIn = Replace(strIn, Chr(13), "<br>", 1, -1, 1) 
    strIn = Replace(strIn, "*|*", "<span class=""Highlight"">") 
    strIn = Replace(strIn, "*||*", "</span>") 
    addHighlight = strIn 
End Function 

當我運行此我得到的顏色格式混合的結果,作爲替代不僅將得到完整的單詞,但是做大的話也子;這不應該發生。 結果應該像這樣結束;

CREATE PROCEDURE AddCityToList 
    -- Add the parameters for the stored procedure here 
    @idCity int, 
    @idProduct int 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for procedure here 
    INSERT INTO CityProductExclude (idCity,idProduct) 
    VALUES (@idCity,@idProduct) 

END 

不在備註中的關鍵詞應該突出顯示並大寫,我怎樣才能得到以下回來;

-- ============================================= 
-- AuthOR: OR,,Name> 
-- CREATE date: <CREATE Date,,> 
-- DESCriptiON: <DESCriptiON,,> 
-- ============================================= 
CREATE PROCEDURE ADDCityTOLISt 
-- ADD the parameters FOR the sTOred PROCEDURE here 
@idCity INt, 
@idProduct INt 
AS 
BEGIN 
-- SET NOCOUNT ON ADDed TO prevent extra result SETs FROM 
-- INterferINg WITH SELECT statements. 
SET NOCOUNT ON; 

-- INsert statements FOR PROCEDURE here 
INSERT INTO CityProductExclude (idCity,idProduct) 
VALUES (@idCity,@idProduct) 

END 

我在想什麼?任何幫助將不勝感激

回答

0

考慮sp.TextBody是一個包含帶有換行符的存儲過程命令的長字符串,通過空格拆分可能不是區分SQL關鍵字和註釋部分的好方法,因此更好地根據換行符進行拆分:

str2 = strIn.Split(New String() { Environment.NewLine }, StringSplitOptions.None) 

通過使用上述分配,它能夠探測到任何字符串開始--爲SQL意見,並讓它們完好無損,因此使用Regex.Replace方法大寫這沒有標記爲評論任何確切的SQL關鍵字:

' Notes: 
' (1) Using System.Text.RegularExpressions required to call Regex.Replace 
' (2) StartsWith used to detect comment section in stored procedure body 
' (3) "\b" + keyWords(keyInd) + "\b" used to replace by whole keywords only 

If Len(Trim(strIn)) > 0 And IsArray(keyWords) Then 
    For keyInd = LBound(keyWords) To UBound(keyWords) 
     For i As Integer = LBound(str2) To UBound(str2) 
      If Not str2(i).StartsWith("--") 
       str2(i) = Regex.Replace(str2(i), "\b" + keyWords(keyInd) + "\b", "*|*" & UCase(keyWords(keyInd)) & "*||*", RegexOptions.IgnoreCase) 
      End If 
     Next 
    Next 
End If 

然後,把所有在一起addHighlight功能:

Function addHighlight(ByVal strIn As String) As String 
    Dim keyWords As Array = searchArr 
    Dim keyInd As Integer 
    Dim str2() As String 
    str2 = strIn.Split(New String() { Environment.NewLine }, StringSplitOptions.None) 
    If Len(Trim(strIn)) > 0 And IsArray(keyWords) Then 
     For keyInd = LBound(keyWords) To UBound(keyWords) 
      For i As Integer = LBound(str2) To UBound(str2) 
       If Not str2(i).StartsWith("--") 
        str2(i) = Regex.Replace(str2(i), "\b" + keyWords(keyInd) + "\b", "*|*" & UCase(keyWords(keyInd)) & "*||*", RegexOptions.IgnoreCase) 
       End If 
      Next 
     Next 
    End If 
    strIn = Join(str2, Environment.NewLine) 
    strIn = Replace(strIn, Chr(13), "<br />", 1, -1, 1) 
    strIn = Replace(strIn, "*|*", "<span class=""Highlight"">") 
    strIn = Replace(strIn, "*||*", "</span>") 
    addHighlight = strIn 
End Function 

注:爲了使這一招工作中,設置strIn內容包括之前像這樣的評論跡象(僅當T-SQL字符串不使用換行符評論前包含換行符):

If Not strIn.Contains(Environment.NewLine) Then 
    strIn = Replace(strIn, "--", Environment.NewLine & "--") 
End If 

演示:.NET Fiddle Example

相關:

Way to have String.Replace only hit "whole words"

+0

謝謝你哲也,我會給這是一個嘗試,讓你知道會發生什麼 –

+0

的代碼做工精細所添加的行,它是如何還曾捕捉關鍵字的評論。我不知道如何阻止這一點,我將不得不玩弄這個看看發生了什麼 –

相關問題