1

我正在做动态报告系统。对于前端,我使用 Asp.net 和 oracle 作为后端。项目要求是,用户可以在 TextBox 中编写查询,并且当在WHERE关键字之后从查询中单击按钮时,所有参数都被拆分。当 ( AND | OR | , ) 将在查询中找到时,拆分将根据模式进行。

例如:-

select * from EmpInfo where age >= 40, active='A' and rownum < 15

结果会

age >= 40
active='A'
rownum < 15

但是如果我在 where 之后使用子查询,那么同样的模式也会遵循

例如:-

select * from EmpInfo where age in (select age from Emp_pns where age >= 60 ), active='A' and rownum < 15

结果会

age >= 60
active='A'
rownum < 15

这是我的示例代码,我尽我所能,但我没有得到完美的解决方案。

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim query As String = TextBox1.Text.ToLower
getParameter(query)
For i As Integer = 0 To ListBox2.Items.Count - 1
    ListBox1.Items.Add(ListBox2.Items(i).Text)
Next
End Sub

Public Sub getParameter(ByVal argument As String)
Dim query As String = argument
Static Dim tempString As String
If query.Contains("order by") Or query.Contains("group by") Then
    Dim mtch As Match = Regex.Match(query, "(?<=where)(.*)(?=order by|group by)")
    Dim mtchString As String = mtch.Groups(1).Value
    tempString = mtchString
    If mtchString.Length >= 1 Then
        Dim bindlist As String() = Regex.Split(mtchString, " and | or |,")
        ListBox1.DataSource = bindlist
        ListBox1.DataBind()
         getParameter(tempString)
    End If
Else
    Dim mtch As Match = Regex.Match(query, "(?<=where)(.*)")
    Dim mtchString As String = mtch.Groups(1).Value
    Dim bindlist As String() = Regex.Split(s, " and | or |,")
    ListBox2.DataSource = bindlist
    ListBox2.DataBind()
End If

End Sub
4

1 回答 1

1

RegexSplit为明确定义的模式提供准确的性能;您正在寻找的模式对于这些方法来说太复杂了(所需的实现太难了,而且无论如何,太死板了)。这种复杂的问题应该依靠字符串分析来解决。使用您的输入字符串(或等效字符串)提供预期结果的示例代码:

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim inputString As String = "select * from EmpInfo where age in (select age from Emp_pns where age >= 60 ), active='A' and rownum < 15"

        Dim whereString As String = inputString.Substring(inputString.ToLower().IndexOf("where") + "where".Length, inputString.Length - (inputString.ToLower().IndexOf("where") + "where".Length)).Trim()
        Dim allParts(whereString.Length + 2) As String
        Dim allPartsCount As Integer = 0
        Dim done As Boolean = False
        If (whereString.Contains("(") And whereString.Contains(")")) Then
            If (whereString.Split("(").Length = whereString.Split(")").Length) Then
                done = True
                Dim remString = whereString
                Do
                    Dim temp = inBrackets(remString)
                    If (temp(0).Trim().Length > 0) Then
                        allPartsCount = allPartsCount + 1
                        allParts(allPartsCount) = temp(0)
                    End If
                    If (temp(1).Trim().Length > 0) Then
                        remString = temp(1)

                    Else
                        Exit Do
                    End If
                Loop While (remString.Trim().Length > 0)
            End If
        End If
        If (Not done) Then
            'Standard treatment
        End If

    End Sub

    Private Function inBrackets(inputString As String) As String()

        Dim outStrings(1) As String

        Dim openBracket As Boolean = False
        Dim count As Integer = -1
        Do
            count = count + 1
            outStrings(0) = outStrings(0) & inputString.Substring(count, 1)
            If (inputString.Substring(count, 1) = "(") Then
                openBracket = Not openBracket
            ElseIf (openBracket And inputString.Substring(count, 1) = ")") Then
                openBracket = False
            End If

            If (Not openBracket) Then
                If (inputString.Substring(count, 1) = ",") Then
                    Exit Do
                ElseIf (count >= "and".Length AndAlso inputString.ToLower().Substring(count - "and".Length, "and".Length) = "and") Then
                    Exit Do
                ElseIf (count >= "or".Length AndAlso inputString.ToLower().Substring(count - "or".Length, "or".Length) = "or") Then
                    Exit Do
                End If
            End If
        Loop While (count < inputString.Length - 1)

        If (outStrings(0).Trim().Length > 0) Then
            outStrings(1) = inputString.Substring(outStrings(0).Length, inputString.Length - outStrings(0).Length)
        End If

        Return outStrings

    End Function
End Class

此代码显示了这种情况的典型方法:您应该根据需要对其进行调整/扩展以满足您的确切要求。它分析只有括号的案例(开/关括号的平行数量)。这个想法非常简单:逐个字符分析给定的字符串,直到找到您正在寻找的“分隔符”之一,另外考虑:如果找到一个左括号,它不会退出循环,直到找到相应的结束一。执行分析的函数返回一个包含当前位和剩余字符串的数组,以便主循环可以继续分析。在任何情况下您都应该做的进一步扩展:考虑括号变化(例如,方括号),考虑嵌套括号(此代码仅考虑“

于 2013-08-08T11:44:59.103 回答