如何解析SQL查询以获取Access中该查询中涉及的表名

时间:2015-10-05 12:57:47

标签: regex vba parsing ms-access ms-access-2010

我决定使用vba和正则表达式来解决这个问题。以下是代码的一部分:

Dim strPattern As String: strPattern = "(FROM|JOIN|from|From|Join|join)\s+([^ ,]+)(?:\s*,\s*([^ ,]+))*\s*"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String

Set MyMatches = regEx.Execute(Form)

If MyMatches.Count <> 0 Then
    With MyMatches
        For myMatchCt = 0 To MyMatches.Count - 1
            If Left(MyMatches.Item(myMatchCt), 6) <> "FROM (" And Left(MyMatches.Item(myMatchCt), 6) <> "JOIN (" Then              
                str = MyMatches.Item(myMatchCt)
                lenght = Len(str)
                format_data = Right(str, lenght - 4)
                pos = InStr(format_data, ")") + InStr(format_data, "(select")
                If pos = 0 Then
                    rst.AddNew
                    rst!block_id = rs("block_id")
                    rst!trans_table = format_data
                    rst.Update
                End If
            End If
        Next
    End With
End if

解析后的表格会写入rst

对于许多类型的查询,它几乎可以正常工作,我只对select个查询感兴趣。但是我无法弄清楚如何处理子查询,例如从这个查询我得到奇数括号(

select *
from (
select * from t1
union 
select * from t2
) t
where 1=1;

那么这里有什么问题?

1 个答案:

答案 0 :(得分:1)

乍一看......

Left(MyMatches.Item(myMatchCt), 6) <> "FROM ("

&LT;&GT;区分大小写

即这是真的      左(&#34;从(&#34;,6)&lt;&gt;&#34; FROM(&#34;

您需要将其更改为

Ucase(Left(MyMatches.Item(myMatchCt), 6)) <> "FROM ("

与&#34; JOIN&#34;类似。条件

我可以看到你为什么要编写自己的代码,因为购买SQL解析器很贵!

以下是我发现的一些文字和链接:

请同时查看以下问题:here其中说明:

RegEx并不擅长这一点,因为它比看起来要复杂得多:

如果他们使用LEFT / RIGHT INNER / OUTER / CROSS / MERGE / NATURAL连接而不是a,b语法怎么办?无论如何都应该避免使用a,b语法。 嵌套查询怎么样? 如果没有表(选择常量)怎么办? 换行和其他空白格式怎么样? 别名? 我可以继续。

你可以做的是寻找一个sql解析器,并通过它运行你的查询。

另请注意: 您想要访问SQL查询的任意子结构(包括子SELECT)吗?你需要的是一个感兴趣的SQL方言的完整解析器。

尝试here

This one会让你回到400美元!我开始明白你为什么要写一篇 - 顺便说一句好。

SQL是一种非常庞大而复杂的语言。可以手动编写递归下降解析器来执行此操作,但这需要相当多的工作。使用解析器生成器和SQL BNF来提供它可能会更好。