SQL-запрос. Получить данные из массива (-ов) или другого (других) Recordset

Весь MS Office, программирование на Visual Basic for Applications и MS VB

Модератор: Naeel Maqsudov

Ответить
tolikt
Сообщения: 93
Зарегистрирован: 29 окт 2005, 12:33
Откуда: NewVasюbirsk

В Excel SQL-запросом из dbf-файла получаю данные. Код такой:

Код: Выделить всё

Dim Data As Variant    
Dim strCnnString As String
Dim rst As ADODB.Recordset
Set cnn = New ADODB.Connection
    
' Строка подключения ODBC.
    strCnnString = "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=" & DirPath & ";"
    ' или для других dbf
    strCnnString = "Driver={Microsoft Visual FoxPro Driver};DriverID=277;UID=;PWD=;" & _
    "SourceDB=" & DirPath & ";SourceType=DBF;Exclusive=No;" & _
    "BackgroundFetch=Yes;Collate=RUSSIAN;Null=Yes;Deleted=No;"
    
cnn.Open strCnnString
    ' Используем метод Execute для создания набора записей.
    Set rst = New ADODB.Recordset
    rst.CursorLocation = adUseClient

sqlString = "SELECT * FROM mydbffile " ' строка запроса

    Set rst = cnn.Execute(sqlString)
    
Err.Clear
On Error Resume Next
    Data = rst.GetRows
If Err.Number = 3021 Then
On Error GoTo 0
ReDim Data(5, 0)
Err.Clear
End If
    
    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing
В итоге получаем двумерный массив Data с необходимыми данными.
Но строка запроса не такая простая, как хотелось бы. Используются операторы UNION ALL, JOIN и т.п. Кроме того, сам запрос состоит из нескольких вложенных запросов. Т.е. строка запроса имеет примерный вид такой:

Код: Выделить всё

SELECT f1, f2, f3 FROM (" & _
    SELECT field1 as f1, field2 as f2, field3 as f3 FROM mydbffile WHERE ...
    UNION ALL SELECT field4 as f1, field5 as f2, field6 as f3 FROM mydbffile WHERE ...
    UNION ALL SELECT field7 as f1, field8 as f2, field9 as f3 FROM mydbffile WHERE ...
    UNION ALL SELECT field10 as f1, field11 as f2, field12 as f3 FROM mydbffile WHERE ...
") WHERE .... & _
LEFT JOIN f1, f2, f3 FROM (" & _
    SELECT field1 as f1, field2 as f2, field3 as f3 FROM mydbffile WHERE ...
    UNION ALL SELECT field4 as f1, field5 as f2, field6 as f3 FROM mydbffile WHERE ...
    UNION ALL SELECT field7 as f1, field8 as f2, field9 as f3 FROM mydbffile WHERE ...
    UNION ALL SELECT field10 as f1, field11 as f2, field12 as f3 FROM mydbffile WHERE ...
") ON .....
и т.д. и т.п.
Т.е. при каждый раз (для каждой части между UNION происходит обращение к dbf-файлу и выборка нужных данных. В итоге время выполнения резко увеличивается.
Если получить некие общие данные только одним обращением к dbf, а потом запросом компоновать так, как надо, то, наверняка, время резко сократится.
Но вот не получается обратиться через Recordset к уже полученному массиву или другому Recordset.
Т.е. как бы сделать примерно это:
SELECT * FROM rst - запрос к рекордсету
или
SELECT * FROM Data - запрос к массиву

Лучше бы, конечно, к Recordset. Т.к. требуется выборка из разных dbf-файлов, которые находятся в разных местах и имеют разный драйвер подключения.
Teslenko_EA
Сообщения: 526
Зарегистрирован: 04 фев 2007, 18:37
Откуда: Сургут
Контактная информация:

Здравствуйте tolikt.
1. SQL запрос может обращаться только к реальному источнику данных, то есть ни к массиву ни к рекордсету запрос обратиться не может.
2. Рекордсет можно создать и открыть без привязки к реальным данным, а заполнить его своим набором данных.
об этом можно прочесть: http://forum.developing.ru/showthread.p ... #post47620
3. К рекордсету может применяться фильтр.
4. Массив динамически изменяется без потери данных - ReDim Preserve
5. Что-то мне подсказывает, что громоздкую конструкцию Вашего запроса можно упростить.

Итог:
Существует возможность "получить некие общие данные" в рекордсет, установить на него фильтр, передать набор записей в массив или другой рекордсет, перегруппировать данные в массиве...
Решение за Вами.
Евгений.
Ответить