来自ACCESS数据库的VBA中的多个INNER JOINS

时间:2015-10-28 12:37:14

标签: excel-vba vba excel

我使用Access查询设计器来设置连接,但它在VBA中不起作用 我在FROM' -2147217900(80040e14)'

中收到语法错误
Set Signal = cnn.Execute("SELECT Table2.W, Table5.Attribute " _
    & " FROM (((((Table7 " _
    & " INNER JOIN Table5 )" _
    & " INNER JOIN Table6) " _
    & " INNER JOIN Table1) " _
    & " INNER JOIN Table2 " _
    & " ON Table1.DB_ID = Table2.Attrib_Def) " _
    & " INNER JOIN Table4 " _
    & " ON Table2.Opt_Obj_ID = Table4.Signal " _
    & " AND Table2.Object_ID = Table4.Node " _
    & " ON Table6.DB_ID = Table4.Signal) " _
    & " INNER JOIN Table3 " _
    & " ON Table4.Node = Table3.Node " _
    & " ON Table5.DB_ID = Table3.Node" _
    & " ON Table7.DB_ID = Table3.Message " _
    & " WHERE (((Table1.Name)='TypeA') " _
    & " AND ((Table7.Name)='XX') " _
    & " AND ((Table6.Name)='X')) ")

1 个答案:

答案 0 :(得分:2)

解决这类问题的最佳方法是将生成的字符串发送到调试/即时窗口:

Sub test()
    Sql = "SELECT Table2.W, Table5.Attribute " _
    & " FROM (((((Table7 " _
    & " INNER JOIN Table5 )" _
    & " INNER JOIN Table6) " _
    & " INNER JOIN Table1) " _
    & " INNER JOIN Table2 " _
    & " ON Table1.DB_ID = Table2.Attrib_Def) " _
    & " INNER JOIN Table4 " _
    & " ON Table2.Opt_Obj_ID = Table4.Signal " _
    & " AND Table2.Object_ID = Table4.Node " _
    & " ON Table6.DB_ID = Table4.Signal) " _
    & " INNER JOIN Table3 " _
    & " ON Table4.Node = Table3.Node " _
    & " ON Table5.DB_ID = Table3.Node" _
    & " ON Table7.DB_ID = Table3.Message " _
    & " WHERE (((Table1.Name)='TypeA') " _
    & " AND ((Table7.Name)='XX') " _
    & " AND ((Table6.Name)='X')) "

    Debug.Print Sql
End Sub

复制出你运行时产生的sql并转到文本编辑器,这样你就可以正确地缩进这个混乱:

SELECT Table2.W, Table5.Attribute  
FROM 
    (
        (
            (
                (
                    (
                        Table7  INNER JOIN Table5 
                    ) 
                    INNER JOIN Table6
                )  
                INNER JOIN Table1
            )  
            INNER JOIN Table2  
            ON Table1.DB_ID = Table2.Attrib_Def
        )  
        INNER JOIN Table4  
        ON Table2.Opt_Obj_ID = Table4.Signal  
            AND Table2.Object_ID = Table4.Node  
        ON Table6.DB_ID = Table4.Signal
    )  
    INNER JOIN Table3  
    ON Table4.Node = Table3.Node  
    ON Table5.DB_ID = Table3.Node 
    ON Table7.DB_ID = Table3.Message  
WHERE 
    (
        (
            (
                Table1.Name
            ) ='TypeA'
        )  
        AND 
        (
            (
                Table7.Name
            )='XX'
        )  
        AND 
        (
            (
                Table6.Name
            )='X'
        )
    ) 

用于生成SQL的Access的GUI就是它在括号中变得愚蠢。在这种情况下,不需要单个括号。我在这里看不到任何超级的东西,但它的丑陋和难以诊断正在发生的事情。而是使用:

SELECT Table2.W, Table5.Attribute  
FROM Table7  
    INNER JOIN Table3
        ON Table3.Message = Table3.DB_ID  
    INNER JOIN Table5
        ON Table5.DB_ID = Table3.Node
    INNER JOIN Table4
        ON Table4.Node = Table3.Node 
    INNER JOIN Table6 
        ON Table6.DB_ID = Table4.Signal
    INNER JOIN Table2
        ON Table2.Opt_Obj_ID = Table4.Signal  
    INNER JOIN Table1
        ON Table1.DB_ID = Table2.Attrib_Def
WHERE
    Table1.Name ='TypeA' AND
    Table7.Name = 'XX' AND
    Table6.Name = 'X';

这更清晰,更容易理解。我们能够删除所有这些parantheses的原因是因为它只有INNER JOINWHERE语句都是'ANDs'。如果那里有一些ORLEFT OUTER JOIN,那么我们必须更加司法化,但我可以向你保证,Access会在那里留下太多括号。它只是爱他们。

无论如何将它放回VBA你可以使用:

Sub test()
    ...all your existing code...

    Dim sql As String

    sql = "SELECT Table2.W, Table5.Attribute"
    sql = sql & " FROM Table7"
    sql = sql & " INNER JOIN Table3"
    sql = sql & "     ON Table3.Message = Table3.DB_ID"
    sql = sql & " INNER JOIN Table5"
    sql = sql & "     ON Table5.DB_ID = Table3.Node"
    sql = sql & " INNER JOIN Table4"
    sql = sql & "     ON Table4.Node = Table3.Node"
    sql = sql & " INNER JOIN Table6"
    sql = sql & "     ON Table6.DB_ID = Table4.Signal"
    sql = sql & " INNER JOIN Table2"
    sql = sql & "     ON Table2.Opt_Obj_ID = Table4.Signal"
    sql = sql & " INNER JOIN Table1"
    sql = sql & "     ON Table1.DB_ID = Table2.Attrib_Def"
    sql = sql & " WHERE"
    sql = sql & " Table1.Name ='TypeA' AND"
    sql = sql & " Table7.Name = 'XX' AND"
    sql = sql & " Table6.Name = 'X';"

    Set Signal = cnn.Execute(sql)
End Sub

最后,无法保证删除括号内容会有所帮助,但它肯定会消除一些歧义并帮助您诊断出它没有正确执行的原因。