2013-08-10 7 views
2

Я хочу получить слово, следующее за частью «FROM» в запросе БД. Иногда со следующим кодом он работает, иногда это не так. Кажется, что это зависит от длины имени таблицы.Получить слово после строки

Private Function GetTableName(Q As String) As String 
    'SELECT * FROM _table WHERE column LIKE '%test%' 

    Dim FROMPos As Integer = Q.ToLower.IndexOf("FROM".ToLower) 

    If FROMPos > -1 Then 
     Dim FirstSpacePos As Integer = Q.ToLower.IndexOf(Chr(32), FROMPos) 

     If FirstSpacePos > -1 Then 
      Dim EndSpacePos As Integer = Q.ToLower.IndexOf(Chr(32), FirstSpacePos + 1) 

      If EndSpacePos > -1 Then 
       'MsgBox(Q.Substring(FirstSpacePos + 1, EndSpacePos - FirstSpacePos)) 
       Return Q.Substring(FirstSpacePos + 1, EndSpacePos - FirstSpacePos) 
      Else 
       Return "" 
      End If 
     Else 
      Return "" 
     End If 
    Else 
     Return "" 
    End If 
End Function 

ответ

1

Иногда хорошее регулярное выражение все, что вам нужно (проверено в LINQPad, поэтому .Dump() вызова).

Dim queries = New List(Of String)() From { _ 
    "select * from my_table", _ 
    "select * from [dbo].[table with spaces] tws where tws.id = @id", _ 
    "select * from [dbo].[table with spaces] tws where tws.id in (select x.id from [some_other_table] x)" _ 
} 

For Each query As String In queries 
    Dim matches = Regex.Matches(query, "from\s+((?:(?:\[[^\]]+\])|[^\s])+)", RegexOptions.IgnoreCase) 
    For Each m As Match In matches 
     m.Groups(1).Value.Dump() 
    Next 
Next 

Результаты:

my_table 
[dbo].[table with spaces] 
[dbo].[table with spaces] 
[some_other_table] 
1

Примечание. Вам, вероятно, будет лучше использовать полный синтаксический анализатор запросов, но он ответит на ваш вопрос.

vb.net

Public Shared Function GetTableName (запрос As String) As String Dim TABLENAME = String.Empty

Dim fromPos = query.IndexOf(" FROM", StringComparison.OrdinalIgnoreCase) 
If fromPos = -1 Then 
    Return tableName 
End If 

tableName = query.Substring(fromPos + 6) 

' check if there is a schema 
If tableName.IndexOf("] ", StringComparison.Ordinal) = -1 Then 
    ' query does not contain [dbo].[tableName] schema 
    tableName = tableName.Substring(0, tableName.IndexOf(" ", StringComparison.Ordinal)) 
Else 
    ' query contains some form of schema 
    tableName = tableName.Substring(0, tableName.IndexOf("] ", StringComparison.Ordinal) + 1) 
End If 

Return tableName 

End Function

C#

public static string GetTableName(string query) 
{ 
    var tableName = string.Empty; 

    var fromPos = query.IndexOf(" FROM", StringComparison.OrdinalIgnoreCase); 
    if (fromPos == -1) 
    { 
     return tableName; 
    } 

    tableName = query.Substring(fromPos + 6); 

    // check if there is a schema 
    if (tableName.IndexOf("] ", StringComparison.Ordinal) == -1) 
    { 
     // query does not contain [dbo].[tableName] schema 
     tableName = tableName.Substring(0, tableName.IndexOf(" ", StringComparison.Ordinal)); 
    } 
    else 
    { 
     // query contains some form of schema 
     tableName = tableName.Substring(0, tableName.IndexOf("] ", StringComparison.Ordinal) + 1); 
    } 

    return tableName; 
} 

Тесты

GetTableName("fkgsejrtlekrjgsdlkfgjsdfg") 
// Returns Empty string 

GetTableName("SELECT * FROM _table WHERE column LIKE '%test%")) 
// Returns _table 

GetTableName("SELECT * FROM SomeReallyReallyLongTableName WHERE column LIKE '%test%")) 
// Returns SomeReallyReallyLongTableName 

GetTableName("SELECT * FROM [dbo].[My Table] WHERE column LIKE '%test%")) 
// Returns [dbo].[My Table] 
+0

"комплексный анализатор запросов" Google реально не показать мне, что им нужно. не могли бы вы дать мне подсказку, что означают? Спасибо! – drumbun

+0

Он означает, что если вы хотите сделать реальный язык, анализируя способ компилятора, вам нужно заглянуть в CFG (http://en.wikipedia.org/wiki/Context-free_grammar). Для GOLDParser доступен грамматик SQL: http://goldparser.org/grammars/ Другим общим парсером языка является ANTLR (http://www.antlr.org/). – mattmc3

Смежные вопросы