Объединение: измените операторы &
на +
, и результат должен быть таким, как ожидалось.
Пропущенные строки: я могу воспроизвести эту проблему, но не могу объяснить ее, кроме как сказатьа) это, вероятно, ошибка, и б) она, вероятно, никогда не будет исправлена: (
Для здравомыслия я протестировал тот же код в SQL Server, и он работает, как и ожидалось.
В целом внешнее соединение может быть смоделировано с использованием объединения и дополнения пропущенных значений например, псевдокод:
( A JOIN B )
UNION
( A NOT MATCH B { A.*, <pad values for B> } )
В вашем случае и в Access SQL:
SELECT Table1.Field_A, Table1.Field_B,
qry_Table2_Combined.Field_A,
qry_Table2_Combined.Field_B,
qry_Table2_Combined.Combined_Field
FROM Table1
INNER JOIN qry_Table2_Combined
ON (Table1.Field_A = qry_Table2_Combined.Field_A)
AND (Table1.Field_B = qry_Table2_Combined.Field_B)
UNION ALL
SELECT Table1.Field_A, Table1.Field_B,
NULL AS Field_A,
NULL AS Field_B,
NULL AS Combined_Field
FROM Table1
WHERE NOT EXISTS ( SELECT *
FROM qry_Table2_Combined
WHERE (Table1.Field_A = qry_Table2_Combined.Field_A)
AND (Table1.Field_B = qry_Table2_Combined.Field_B) );
Вышепохоже, дает ожидаемые вами результаты.
Доступ к репро-коду с исправлением конкатенации, раскомментированный код для предлагаемого обходного пути:
Sub EXfewfTempler()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = "CREATE TABLE Table1 ( Field_A VARCHAR(10), Field_B VARCHAR(10) );"
.Execute Sql
Sql = "CREATE TABLE Table2 ( Field_B VARCHAR(10), Col_1 VARCHAR(10), Col_2 VARCHAR(10));"
.Execute Sql
Sql = "CREATE VIEW qry_Table2_Combined AS SELECT '2' AS Field_A, Table2.Field_B, Table2.Col_1 + ', ' + Table2.Col_2 AS Combined_Field FROM Table2; "
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (1, NULL);"
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (1, NULL);"
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (2, 1);"
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (2, 2);"
.Execute Sql
Sql = "INSERT INTO Table2 VALUES (1, 'John', 'Doe');"
.Execute Sql
Sql = _
"SELECT " & _
"Table1.Field_A, " & _
"Table1.Field_B, " & _
"qry_Table2_Combined.Field_A, " & _
"qry_Table2_Combined.Field_B, " & _
"qry_Table2_Combined.Combined_Field " & _
"FROM Table1 " & _
"LEFT JOIN qry_Table2_Combined " & _
" ON (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
"AND (Table1.Field_B = qry_Table2_Combined.Field_B);"
' Sql = _
' "SELECT Table1.Field_A, Table1.Field_B, " & _
' " qry_Table2_Combined.Field_A, " & _
' " qry_Table2_Combined.Field_B, " & _
' " qry_Table2_Combined.Combined_Field " & _
' " FROM Table1 " & _
' " INNER JOIN qry_Table2_Combined " & _
' " ON (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
' " AND (Table1.Field_B = qry_Table2_Combined.Field_B) " & _
' "UNION ALL " & _
' "SELECT Table1.Field_A, Table1.Field_B, " & _
' " NULL AS Field_A, " & _
' " NULL AS Field_B, " & _
' " NULL AS Combined_Field " & _
' " FROM Table1 " & _
' " WHERE NOT EXISTS ( SELECT * " & _
' " FROM qry_Table2_Combined " & _
' " WHERE (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
' " AND (Table1.Field_B = qry_Table2_Combined.Field_B) );"
Dim rs
Set rs = .Execute(Sql)
MsgBox rs.GetString(2, , vbTab & vbTab, , "<NULL>")
End With
Set .ActiveConnection = Nothing
End With
End Sub