Доступ к SQL-запросу объединения

Я использую 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 ответ

Решение

Параметризация имен таблиц или условный выбор из таблицы на основе существования таблицы не работает в базе данных, о которой я знаю на уровне sql. Вместо этого вы должны динамически создавать SQL.

Ниже приведен пример создания двумерного массива, который содержит список имен таблиц с именем столбца номера телефона. Динамически строит строку SQL и задает определение запроса для этой строки SQL. Предположительно, вы бы назвали это при запуске или всякий раз, когда вам это нужно.

Он использует реализацию Contains в Vadim, но вы могли бы вместо этого запросить MsysObjects. Это также требует существующего MasterList определение запроса

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
Другие вопросы по тегам