我决定使用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;
那么这里有什么问题?
答案 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来提供它可能会更好。