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

How to parse SQL query to get table names involved in that query in Access

我决定使用 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;

那么这里有什么问题?

乍一看...

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

<> 区分大小写

也就是说这是真的 左("From (", 6) <> "FROM ("

您需要将其更改为

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

与"JOIN"条件类似

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

这是我找到的关于此的一些文本和链接:

另请参阅此 SO 问题:here 其中指出:

RegEx 不太擅长这个,因为它比看起来要复杂得多:

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

您可以做的是寻找 sql 解析器,然后 运行 通过它进行查询。

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

尝试here

This one 将花费您 400 美元!我开始明白你为什么要写一个了 - 顺便说一句很好。

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