2015-10-05 44 views
1

我決定使用vba和正則表達式解決此問題。以下是部分代碼:如何解析SQL查詢以獲取涉及該查詢中的表名稱Access

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

乍一看...

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

<>是大小寫敏感

即這是真實的 左( 「發件人(」,6)<> 「FROM(」

您需要將其更改爲

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

同樣與「加入」條件

我可以看到你爲什麼要編寫自己的代碼,因爲購買SQL解析器是昂貴的!

這裏的一些文字和鏈接,我發現這一點:

請另見本SO問題:here其中規定:

正則表達式是不是在這個非常好,因爲它的很多比它更復雜出現:

如果他們使用LEFT/RIGHT INNER/OUTER/CROSS/MERGE/NATURAL連接而不是a,b語法怎麼辦?無論如何應該避免使用a,b語法。 嵌套查詢呢? 如果沒有表格(選擇一個常量)會怎麼樣 換行符和其他空格式格式如何? 別名? 我可以繼續。

你可以做的是尋找一個SQL解析器,並通過它來運行你的查詢。

另請注意: 您想要訪問SQL查詢的任意子結構(包括子SELECT)嗎?你需要的是一個完整的SQL語言解析器。

嘗試here

This one將設置你回到$ 400!我開始明白你爲什麼寫一個 - 順便說一句。

SQL是一個相當大且複雜的語言。可以手動編寫遞歸下降解析器來完成這個任務,但這是相當多的工作。用分析器生成器和SQL BNF來提供它可能會更好。附件:

+0

PS。我讀到這個共享軟件基於Access VBA的框架(60美元)https://www.arrow-of-time.com/AXF.aspx有一個SQL解析器。我沒有使用它。 – HarveyFrench