Visual Basic 6 и dbf: проблемы с «join» и «where» - PullRequest
0 голосов
/ 21 января 2019

Мне нужно изменить старое приложение vb6, которое должно импортировать некоторые данные из базы данных dBase IV.В прошлом запрос на выборку включал одну таблицу (файл dbf) и работал идеально.

Теперь мне нужно отредактировать этот запрос, чтобы ввести объединение для второй таблицы, используя несколько полей.

Это упрощенная версия моего кода:

Dim cnn As New Connection
Dim rs As New Recordset
Dim sql As String

cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Extended properties=dBase IV;Data source=d:\100\db;"

sql = "..." 'see below!

rs.CursorLocation = adUseClient
rs.Open sql, cnn, adOpenDynamic, adLockOptimistic

debug.print rs.RecordCount

rs.Close
cnn.Close

Эти две таблицы имеют типичную структуру основных деталей;Я проверил документацию по БД и проверил TABFAT01 и TABFAT02, поэтому могу предположить, что:

  • Соединение между этими таблицами равно [TABFAT01] 1 <-> n [TABFAT02] и выполняется на TIPDOC (text), ANNDOC (text) и NUMDOC (numeric)fields.
  • Каждая строка в TABFAT01 имеет как минимум 1 объединенную строку в TABFAT02.
  • Каждая строка в TABFAT02 имеет 1 объединенную строку в TABFAT02.
  • TABFAT01 имеет 63 записи.
  • TABFAT02 имеет 907 записей.

Первый выпуск

Мой первый запрос:

select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT01 t inner join 
     TABFAT02 c on t.TIPDOC = c.TIPDOC and t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC

Этот запросвозвращает 0 записей.

Если я изменяю порядок условий следующим образом:

select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT01 t inner join 
     TABFAT02 c on t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC and t.TIPDOC = c.TIPDOC

, запрос возвращает 907 записей.

Я не понимаю, как и почему порядок условий имеетвлияние на результаты запроса.

Вторая проблема

Если я добавлю предложение where:

select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT01 t inner join 
     TABFAT02 c on t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC and t.TIPDOC = c.TIPDOC
where c.LIBER04 = 'a'

, запрос вернет 0 записей.

Однако, если я выполню этот запрос:

select * from TABFAT02 c where LIBER04 = 'a'

, он вернет 1 запись с TIPDOC = 'F2', ANNDOC = '2018', NUMDOC = 1854.

Последующийquery:

select * from TABFAT01 t where t.TIPDOC = 'F2' and t.ANNDOC = '2018' and t.NUMDOC = 1854

возвращает 1 запись, как и ожидалось.

Это происходит для каждого поля, которое я пытался вставить в предложение where со связанными таблицами, кроме TIPDOC.Если я отфильтрую по TIPDOC, результаты будут правильными.

Третий выпуск

При первом запуске кода после открытия vb6 IDE он даетследующая ошибка:

Run-time error '-2147467259 (80004005)': Selected Collating sequence Not Supported by the operating system.

(на самом деле я использую итальянскую версию vb6, и в оригинальном сообщении об ошибке говорится «Sequenza di ordinamento selezionata non supportata dal sistema operativo.». Я предполагаю, что сообщение, которое я написал выше,правильное соответствие для английской версии.)

Эта ошибка не отображается при последующих запусках, , пока я не закрою и не открою vb6 .

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Я согласен с thx1138v2 о том, что не следует использовать драйвер Jet OleDB, но есть еще один конкретный источник. Вы упоминаете dBASE IV. Это точно или это действительно с Visual FoxPro. Вы можете подтвердить, что в таблице есть индексы и поля примечаний (заметок), к именам файлов будет добавлен суффикс

YourTable.dbf (фактическая таблица) YourTable.cdx (файл составного индекса) YourTable.fpt (содержимое файла заметок / заметок в таблице содержит такие столбцы).

Подтвердив, и если это Visual Foxpro, я бы получил драйвер Microsoft непосредственно от Microsoft

Если таблица данных обновляется из источника вне VFP, то возможно, что индексы могут быть не синхронизированы, так как другие драйверы не обязательно будут правильно открывать файл индекса (cdx), чтобы сохранить новые записи в синхронизация. Поэтому при попытке выполнить объединение на основе одной серии предложений объединения он использует несинхронизированный индекс. Но изменение порядка приводит к тому, что по умолчанию устанавливается естественный порядок, поэтому отображаются все возможные записи для разрешения.

Видите, и, надеюсь, это имеет смысл и помогает настроить недостающее звено в вашей проблеме с запросом.

0 голосов
/ 22 января 2019

Сначала очистите ваше сообщение об ошибке. «Выбранная последовательность сортировки не поддерживается операционной системой». возможно, это означает, что вы не указали последовательность упорядочения или драйвер Jet.OLEDB не поддерживает заданную последовательность упорядочения.

Я никогда не получал драйверы Jet.OLEDB для работы с моим приложением. Я думаю, потому что файлы, с которыми я имел дело, были созданы FoxPro. Поэтому я использовал ODBC-драйверы Visual Fox Pro. Вот пример подключения. "DSN = BCLVariance; UID =; SourceDB = C: \ AMSI \ BCLTemp; SourceType = DBF; Exclusive = Да, BackgroundFetch = Нет; Разобрать = машина; Null = Да; Deleted = Yes;" Вы увидите, что он позволяет вам контролировать различные параметры, которые вы не контролируете в строке подключения Jet.OLEDB. Источник данных ODBC настраивается на вкладке Системные источники данных в Администраторе источника данных ODBC.

Я никогда точно не понимал, почему, но последовательность, в которой вы указываете имена таблиц в запросе SQL, действительно имеет значение. Это связано с тем, как их обрабатывает внутренний интерпретатор запросов. Сначала необходимо указать таблицу сведений, а мастер присоединяется к детали. Как это:

select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT02 c inner join 
     TABFAT01 t on t.TIPDOC = c.TIPDOC and t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC

Это может также решить ваши другие проблемы. Попробуйте.

Кстати, вам также нужно изменить исходный код на:

if Not rs.BOF then
    rs.MoveLast
    debug.print "rs.RecordCount=";rs.RecordCount
else
    debug.print "rs.BOF = True"
end if
...