访问SQL联合查询

时间:2013-06-11 20:25:40

标签: sql ms-access-2007 union exists not-exists

我使用Access 2007并且对此比较陌生,所以请耐心等待。

情况

我创建了一个简化的例子来分享。

我的数据库中有一组表经常更改。有时会有十几个表,有时只有4或5.有一组重要信息由所有表共享,我想将这些数据收集到一个新表中。

示例:假设我们有以下表格和字段:

 Table1 : Name, PhoneNumber, PostalCode,...
 Table2 : Name, Phone, PostalCode, Address,...
 Table3 : Name, PhoneNo, Address, DateOfBirth,...
 Table4 : Name, PhoneNumber, Favorite Food, ...
 Etc....

我已经写了一个查询,将重要信息(在这种情况下:姓名和电话号码)收集到一个'主列表中:

 SELECT Name, PhoneNumber 
 FROM Table1
 UNION
 SELECT Name, Phone AS PhoneNumber
 FROM Table2
 UNION 
 SELECT Name, PhoneNo AS PhoneNumber
 FROM Table3
 UNION
 etc...
 ;

问题

我正试图找到一种方法来编译同样的主列表'即使某些表格不在数据库中。假设我们只有Table1和Table3。无论如何都要将表添加到联合查询只有它存在?就像我在SQL一样糟糕,我在VBA时更糟糕。不知怎的,我怀疑那里有可能,但我想我会问。

基本上,我试图将其转换为SQL:

 SELECT Name, PhoneNumber 
 FROM Table1 (IF IT EXISTS)
 UNION
 SELECT Name, Phone AS PhoneNumber
 FROM Table2 (IF IT EXISTS)
 UNION 
 SELECT Name, PhoneNo AS PhoneNumber
 FROM Table3 (IF IT EXISTS)
 UNION
 etc...
 ;

我收到一条错误消息,指出Access无法找到输入表。 我发现我可以使用以下代码来确定表是否存在:

 SELECT Count(*) AS Exists, "Table1" From MsysObjects
 WHERE type=1

解决方案是否有可能涉及此问题?

提前致谢!!

1 个答案:

答案 0 :(得分:1)

参数化表名或根据表存在而有条件地从表中选择并不在我知道的sql级别的数据库中工作。相反,您必须动态创建SQL。

下面是一个创建二维数组的示例,其中包含一个表名列表及其电话号码列名。动态构建sql字符串并将查询定义设置为该sql字符串。大概你可以在启动或任何其他需要的时候调用它。

它使用Vadim的implementation of Contains,但您可以查询MsysObjects。它还需要现有的MasterList查询def。

Sub Test()

    Dim tableNames(3, 2) As String
    tableNames(0, 0) = "Table1"
    tableNames(0, 1) = "PhoneNumber"

    tableNames(1, 0) = "Table2"
    tableNames(1, 1) = "Phone"

    tableNames(2, 0) = "Table3"
    tableNames(2, 1) = "PhoneNo"

    Dim i As Integer
    Dim sql As String


    For i = 0 To UBound(tableNames, 1)

         If Contains(CurrentDb.TableDefs, tableNames(i, 0)) Then

            sql = sql + " SELECT Name, " & tableNames(i, 1) & " as PhoneNumber "
            sql = sql + " FROM Table1 " & tableNames(i, 0)
            sql = sql + "  UNION"
         End If
    Next

    If Len(sql) >= Len(" UNION") Then
        sql = Left(sql, Len(sql) - Len(" UNION"))
    Else
        sql = ""
    End If

    If sql <> "" Then
        CurrentDb.QueryDefs("MasterList").sql = sql
    End If


End Sub

Public Function Contains(col As Variant, key As Variant) As Boolean
Dim obj As Variant
On Error GoTo err
    Contains = True
    obj = col(key)
    Exit Function
err:

    Contains = False
End Function