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
4

2 回答 2

1

请注意,使用综合查询解析器可能会更好,但它确实回答了您的问题。

VB.net

公共共享函数 GetTableName(query 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

结束功能

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]
于 2013-08-10T04:03:03.177 回答
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]
于 2013-08-10T13:01:29.020 回答