Статьи Королевства Дельфи

ADO и файлы xBASE и Paradox


Итак, мы смогли наладить работу через ADO к файлам формата MS Access. Но ведь мы можем и должны использовать файлы xBase и Paradox в качестве обменных файлов.

Попробуем это сделать. Все примеры какие я видел в книгах работают одинаково - через 'Microsoft OLE DB provider for ODBC'. А все редакторы, которые делают строку подключения, всегда показывают только mdb файлы в диалоге, в котором задается путь к файлу БД. Что-то тут нечисто, подумал я - а как же тот же самый Access это делает? Ведь явно не через ODBC, стало быть, есть какая-то хитрость.

После примерно недельных поисков в Интернете решение было найдено. Да, действительно можно использовать 'Microsoft Jet 4.0 OLE DB Provider'. Чтобы не рассказывать долго, представим, что у нас на диске D в корне лежит файл Test.dbf формата dBase 5.0.
Строка коннекта для этого случая будет выглядеть так:
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\; Extended Properties=dBase 5.0; Mode=Read|Write|Share Deny None; Persist Security Info=True';

И это все. Самое интересное во всей это строке - секция 'Extended Properties'.
Чтобы знать, что конкретно для разных форматов надо писать в Extended properties, загляните в реестр Windows на следующую ветку:
HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\ISAM Formats

Там перечислены все поддерживаемые в данном случае форматы.

После опытов над форматом dbf оказалось, что все выше сказанное для формата mdb совершенно не относится к этому формату - и все требования про первую форму можно и не соблюдать! В общем, загадка природы.

А вот формат Paradox - это оказалась песня на меньшая, чем mdb. И вот почему - здесь все требования о первой форме таблицы в действии, но ведь мы не можем создавать таблицу, потом говорить пользователю 'Слышь, мужик, а теперь метнулся, запустил Paradox и создал первичный ключ на эту таблицу. А потом нажмешь на ОК и мы продолжим'. Это несерьезно. Стало быть, этот ключ надо создавать нам самим.

Хорошо, запускаем справку по MS Jet SQL и ищем раздел создания индексов или первичных ключей. Находим следующее: CREATE INDEX имя_индекса ON название_таблицы (название_поля) WITH PRIMARY. ALTER TABLE название_таблицы ADD CONSTRAINT имя_ограничения PRIMARY KEY (название_поля) Все далее сказанное абсолютно одинаково для обоих вариантов.


Предположим, что наша таблица называется ExpTbl.db и поле, на которое мы хотим наложить первичный ключ, называется IntrernalID. Хорошо, подключаемся к таблице и задаем такую строку SQL для исполнения: CREATE INDEX My_Index ON ExpTable (InternalID) WITH PRIMARY

Запустим на выполнение. Ого, а что это мы видим? Вот те на - очередное сообщение об ошибке. При этом сообщение как всегда очень содержательное применительно к нашему случаю.
Неправильных символов нет, синтаксис правильный, длина названия ключа тоже нормальная. Я так думаю потому, что если выполнить это через BDE, все будет работать со свистом.

Вывод один - опять очередное требование ADO, которое сразу не поймешь. Ладно, запускаем он-лайн MS MSDN и делаем запрос на PARADOX. Видим что-то около 50 документов. И где-то в 35-36 документе я нашел ответ маленькими буковками внизу экрана! Сейчас я вам скажу в чем проблема - держитесь крепче: имя первичного ключа должно совпадать с названием таблицы, а имена индексов с именами полей. Неслабо.
Исправляем SQL: CREATE INDEX ExpTable ON ExpTable (InternalID) WITH PRIMARY Запускаем, смотрим - все отлично.

Чтобы никто больше мучился с этим делом, я хотел бы привести самые значащие ограничения для драйвера PARADOX, которые я нашел в MSDN:
  1. Для того, чтобы Вы имели возможность производить действия по добавлению, удалению записей или редактированию данных в таблице, таблица должна иметь первичный ключ.
  2. Первичный ключ должен быть определен для первых 'n' полей таблицы.
  3. Вы не можете создавать для таблицы индексы, если для нее не определен первичный ключ.
  4. Первый создаваемый для таблицы уникальный индекс будет создан как первичный ключ.
  5. Первичный ключ может быть создан для таблицы только в том случае, если в ней нет ни одной записи.
  6. Действия по добавлению или удаления полей в таблице должны быть произведены до того, как для нее создан первичный ключ.
Кстати, по моему опыту удалить однажды созданный первичный ключ для таблицы невозможно.

Итак, для работы через ADO с файлами xBase или Paradox, нам необходимо указывать нужный драйвер в секции Extended Properties и в секции Data Source только путь до файла. Для xBase на этом все трудности закончены, а вот для Paradox необходимо задание первичного ключа как для формата MS Access, при этом есть определенные ограничения при задании названий ключей, так же как и возможных индексов.



То, о чем речь пойдет далее уже не относится к организации работы с таблицами xBase и Paradox через ADO, а скорее упоминание об одном полезном опыте.
Для добавления данных в эти таблицы, мы можем вставлять их по одной (Table.Append (Insert); Table.Post), а можем воспользоваться вариантом SELECT … INTO, INSERT … INTO. Поговорим теперь именно о втором варианте работы.

Смотрим файл справки MS Jet SQL. SELECT поле_1 [, поле_2 [, ...]] INTO новаяТаблица [IN внешняяБазаДанных] FROM источник

Ладно, пробуем. Пусть мы имеем в качестве источника данных mdb файл и хотим сохранить данные из таблицы SourceTable в таблицу формата Paradox 7.0 TestTable.db, расположенную в корне диска D:. Казалось бы: SELECT * INTO [TestTable.DB] IN 'D:\' FROM SourceTable

Нет, очередная ошибка. Вот, что мы видим.

Ага, хорошо, давайте попробуем указать таблицу в пути: SELECT * INTO [TestTable] IN 'D:\ TestTable.DB' FROM SourceTable

Получим очередное сообщение об ошибке.



Ага, стало быть, файл для экспорта должен уже существовать? Ладно, не проблема, давайте создадим его и попробуем еще раз.



Ну, в общем, желающие могут еще поэкспериментировать, а для остальных я скажу как делается: SELECT * INTO [Paradox 7.x;DATABASE=D:\].[TestTable#DB] FROM SourceTable

Создавать таблицу до операции экспорта нет надобности - таблица будет создана автоматически, все поля будут созданы правильного типа. В получившейся таблице будут все данные из SourceTable.
Единственная проблема - Вы не сможете больше редактировать данные в этой таблице, потому (см. выше) для этого необходим первичный ключ, а создать его для таблицы, в которой уже есть записи нельзя.

Самое потрясающее это название раздела MSDN, где я нашел этот ответ - 'Как, используя ADO, открыть таблицу Paradox, защищенную паролем'. Как ЭТО имеет отношение к этому синтаксису SQL, я так и не понял, честно говоря.

Вот, в общем-то, все, что я хотел написать. Осталось еще много интересного в этой области. Чего стоит, например установка правильных кодовых страниц для результирующих файлов и много чего подобного. Это тема либо для продолжений этой статьи, либо для отдельных статей. Очень надеюсь, что кто-нибудь нашел тут полезные для себя сведения.

Иванов Денис Михайлович.
14 мая 2001г.
Специально для

При написании статьи использовались следующие материалы:
  1. Материалы .
  2. Справочные файлы Delphi 4 и Delphi 5.
  3. Исходные коды VCL Delphi 4 и Delphi 5.
  4. и примеры MS ADO SDK.
  5. .
  6. А.Я. Архангельский 'Язык SQL в Delphi 5'.


Содержание раздела