powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Другие СУБД [игнор отключен] [закрыт для гостей] / Взаимодействие с Btrieve из Delphi
30 сообщений из 30, показаны все 2 страниц
Взаимодействие с Btrieve из Delphi
    #33236504
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток!

Нашел на этом сайте статью на тему подключения к бтривовским файлам из Дельфи. Для прямого подключения к базе с использованием Btrieve API необходимо расписать в программе структуру таблицы (добавляется тип record с полями, соответствующими названиям полей в таблице). При этом размеры и типы полей должны точно соответствовать (например, unsigned int, 4 byte (в таблице) -> longword (Дельфи)).

Так вот, одну таблицу, где "нормальные" типы полей, я смог открыть, все замечательно. Но в другой есть поле типа, который называемый "COBOL Decimal Comp-3", длиной 3 байта... Слово Decimal явно говорит о том, что тип - числовой. Но числового типа длиной 3 байта в Delphi нет. Позволяет ли Дельфи как-то обойти такую ситуацию? Добавить свой вещественный тип?
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33237975
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это упакованный с фиксированной десятичной точкой - каждая цифра 0-9 занимает полбайта, последний полубайт - знак числа - 16-чные A?,С,E?,F = + (положительное),B?,D = - (отрицательное) (там где вопросики я не уверен). Положение десятичной точки в самом числе не хранится. Таким образом в 3 байтах 3*2-1 = 7 значное число. Но это может быть любое: 7,0 7,1 ... 7,7. В стандартном Delphi до 5 версии аналогов не было, но были стороние библиотеки. Это один из числовых форматов EDBSCI или EBDSCI (или както похоже - точно не помню) разработанный еще для HAVI METAL (IBM 360/380).
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33238018
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо.
Я, оказывается, выход нашел сразу, описал это поле как array [0..2] of char (значение этого поля меня не интересует).

Но таблица не открывалась не по этой причине. Я выгружал таблицу docdep.dat (2Гб) (кто знает - это балансовые проводки в АБС-ке Diasoft Card). Так вот, открыть этот файл невозможно, если рядом с ним не лежит файл docdep.^01 (еще 400 метров :)). Кто-нибудь подскажет, что это за файл и нафига он нужен?
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33240124
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Btrieve таблицы не зависимы в том плане что нет запрета что-то читать отдельно - скорее всего ты натыкаешься на другие ограничения - например длину файла.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33240236
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
golsaВ Btrieve таблицы не зависимы в том плане что нет запрета что-то читать отдельно - скорее всего ты натыкаешься на другие ограничения - например длину файла.

Да, так и есть, файл оказался продолжением того же docdep-a.

Осталась вроде последняя проблема.

Btrieve позволяет искать записи только по тем полям, которые описаны в индексах. Я в программе использую для выборки записей функцию BTRVID. Так вот, на таблице есть несколько индексов: несколько по одному полю, и несколько составных. По индексам из одного поля ищет нормально, а по составному просто возвращает первую запись в файле. В чем тут может быть загвоздка?

Вот фрагмент кода:
...
//присваем значение индекса
DocdepIndex0.datetrf := 73777;
DocdepIndex0.crncode:=840;
DocdepIndex0.batch:=1;
DocdepIndex0.doctype:=#1;
DocdepIndex0.ddp_auto:=2120656;
...
fillchar(DocdepRecord , SizeOf(DocdepRecord), #0);
dataLen := sizeof(Docdep_STRUCT);
//Дальше вызов функции BTRVID:
status := BTRVID(B_GET_FIRST,
PosBlock,
DocdepRecord,
dataLen,
DocdepIndex0,
0,
client);
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33240375
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Строку
fillchar(DocdepRecord , SizeOf(DocdepRecord), #0);
попробуй перенести выше - перед присвоением значений структуре DocdepRecord.

Перед чтением установи индекс (должна быть специальная функция-команда что-то типа B_SET_INDEX) по которому будет поиск. Индексы не имеют имен, они нумеруются в порядке создания - вот только с 0 или 1 - точно не помню (кажется все же с 0). Функции передается номер индекса. Если запустить утилиту
BUTIL -STAT <имя файла>
получишь список индексов в порядке их создания. Или посмотреть в DDF файлах - номер там присутствует.

B_GET_FIRST - чтение первой записи, если индекс не уникальный следующие записи читать B_GET_NEXT (должно быть както так)
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33240564
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про строку в предыдущем посте я зря. Не могли бы вы послать на gol-sa@mail.ru файлики из Pervasive SQL SDK для Delphi.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33240836
VNS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
golsaПро строку в предыдущем посте я зря. Не могли бы вы послать на gol-sa@mail.ru файлики из Pervasive SQL SDK для Delphi.

Издевается.

Зайдите на pervasive.com
там есть куча всяких библиотек для разработчиков чего только не упомнишь.
А здесь если не ошибаюсь куча всяких ddf эдиторов.

Pervasive это контора которая в свое время купила btrieve у новела
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33241156
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Номер и структуру индекса я посмотрел как раз в DDF - это 0-й индекс (номер указан в предпоследнем параметре BTRVID). Причем DDF этот рабочий, т.е. верно отражает структуру таблицы (он используется давно для подключения через ODBC).

"Перед чтением установи индекс (должна быть специальная функция-команда что-то типа B_SET_INDEX) по которому будет поиск. "

Попробую покопаться еще, но навскидку в хелпе и *.pas файлах из SDK ничего подобного не вижу... Файлики сейчас Вам вышлю, возможно, Вы вспомните?
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33242397
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я email написал неправильно - надо gol_sa@mail.ru
Посмотри еще на RECORD для индекса - там может надо отменить выравнивание - PACKED RECORD. В строковых переменных вполне возможно надо расширять до полной длины пробелами. В зависимости от типа в BTRIEVE строковые переменные иногда приходится заменять на массивы типа CHAR (без байта длины в начале и без 0 в конце).
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33242436
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня все строковые поля так и объявлены: array [0..n] of char. Packed попробовал убрать, не помогает. Процесс начинает напоминать танцы с бубном вокруг Btrieve.

Вот, пока писал, пришла в голову мысль, что наверняка надо заполнять все поля в индексе? Я-то так и делаю, но в общем случае совсем неудобно получается.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33242563
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При точном (B_GET_EQUAL) поиске надо заполнять все поля. Для команд B_GET_LESS (меньше) и B_GET_GREATER (больше) можно только по старшим полям индекса (любое кол-во полей с начала RECORDа без перерыва, остальные до конца RECORDа для стабильного результата затереть $0). Данные, которые передаются в BTRVID() больше никак не преобразуются, поэтому надо точно знать как их заполнять. Возьми любой 16-чный вьюер и рассмотри свой файл - найди там какую-нибудь запись. Вычлени поля индекса. Потом заполни данными свой RECORD и посмотри на его 16-ричный образ (можешь в файл записать). Образ должен один в один совпадать с полями индекса выбранными из записи. Учти в чистом BTRIEVE индекс может строится не по целым полям - просто там для индекса задается массив смешений от начала записи и длин (могут даже пересекаться!). Но к Pervasive SQL это не относится - в DDF индексы описываются только полями.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33243078
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Блин, у меня складывается впечатление, что Pervasive на индекс при поиске вообще не обращает внимания. Я ему четко указал: DocdepIndex0.crncode:=840;
В результате он находит строку (BTRVID<>B_KEY_VALUE_NOT_FOUND), но в ней crncode=810!

DocdepIndex0.crncode:=840;
DocdepIndex0.datetrf := $0;
DocdepIndex0.batch:=$0;
//строка
DocdepIndex0.doctype:=#0;
DocdepIndex0.ddp_auto:=$0;

fillchar(DocdepRecord , SizeOf(DocdepRecord), #0);
dataLen := sizeof(Docdep_STRUCT);
status := BTRVID(B_GET_FIRST, {системная константа}
PosBlock, {системная}
DocdepRecord, {сюда будет возвращен результат поиска}
dataLen, {см.выше}
DocdepIndex0, {см.выше}
0, {номер индеска - см.выше}
client); {системная}

//А выводит '0 810'
if status<>B_KEY_VALUE_NOT_FOUND then
showmessage(inttostr(status)+' '+floattostr(docdeprecord.crncode)) else
showmessage('Не найдено');
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33243264
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только команды B_GET_EQUAL,B_GET_LESS,B_GET_GREATER или разновидности двух последних (не знаю как называются константы) меньше или равно B_GET_LESS_OR_EQUAL? и больше или равно B_GET_GREATER_OR_EQUAL? используют значения DocdepIndex0 для позиционирования.

Команда B_GET_FIRST - дать первую запись файла в сортировке по индексу!
Т.е. это начало последовательного чтения файла по индексу.

Более подробно см http://emanual.ru/download2/2172.html#CONTENTS глава 6.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33243733
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если в том же вызове BTRVID B_GET_FIRST заменить на B_GET_GE (GREATER OR EQUAL), BTRVID возвращает 2 (IO Error). Ничего не понимаю: записи с crncode>840 точно есть (код валюты 978 - евро)
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33244911
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда скорее всего структура индекса не соответствует DocdepIndex0. Или попробуй номер индекса = 1 (вдруг с 1 нумерация).
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33246927
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
golsa... попробуй номер индекса = 1 (вдруг с 1 нумерация).

Эврика!

Я-то ориентировался на DDF, считая, что там должна быть абсолютно точно расписана структура таблица, включая индексы. А на самом деле получается, что нулевой индекс в ДДФ-е пропущен. Т.е. в DDF на месте 0-го индекса стоит 1-ый, по которому я и пытался сделать поиск. Спасибо за помощь!
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33247114
RAndrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все-таки проблемы не кончились. Когда в программе я нахожу по индексу первую запись, далее начинаю в цикле выбирать все записи, удовлетворяющие заданному условию. Так вот, после нескольких сот итераций (записей) снова вываливается статус=2 (IO_Error) (причем для конкретного условия при каждом запуске нормально выбирается одно и то же число записей). Не могу понять, что ему нужно на этот раз.

//условие поиска
DocdepIndex8.datetrf:=74726;
DocdepIndex8.mainddp_auto:=$0;
DocdepIndex8.conv_auto:=$0;

//находим первую строку
fillchar(DocdepRecord , SizeOf(DocdepRecord), #0);
dataLen := sizeof(Docdep_STRUCT);
status := BTRVID(B_GET_GE, PosBlock, DocdepRecord, dataLen, DocdepIndex8,
8, client);

//просматриваем все записи, удовлетворяющие условию поиска
while (status=B_NO_ERROR) and (status<>9) and (docdeprecord.datetrf=74726) do begin
fillchar(DocdepRecord , SizeOf(DocdepRecord), #0);
dataLen := sizeof(Docdep_STRUCT);

status := BTRVID(B_GET_NEXT,PosBlock,DocdepRecord,
dataLen, DocdepIndex8, 8, client);
label1.Caption:=inttostr(i);
label2.Caption:=inttostr(status);
application.ProcessMessages;
i:=i+1;
end;
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33247331
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Внешне код нормальный - погляди данные не длинее они заказаного в dataLen? (у Btrieve могут быть записи переменной длины), выведи значение dataLen после BTRVID() - он не меняется? может индекс битый? или сам файл? Или каким-то образом портятся данные в структуре PosBlock? В ней хранится информация о позиции текущей записи в файле (т.е. меняется при каждом BTRVID()), которая используется командой B_GET_NEXT.
Сделай с помощью утилиты BUTIL (см. в каталоге BIN Pervasive) выгрузку данных (-SAVE), потом создание нового файла по шаблону (-CLONE) и загрузку в него данных (-LOAD). Индексы перестроятся, заодно полюбуешься на текстовый файл выгруженных данных. Попробуй отыскать запись, на которой сваливается программа.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33248088
bpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При 2-ой ошибке нужно базу лечить однозначно.

Пользуйся компонентами из PDAC Pervasive , ими можно как SQL запросами так и прямым доступом к таблице пользоваться, тем более что в PSQL v9 значичельно расширены возможности SQL, вплоть до встроенных функций.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33248116
Len@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
RAndrey
Так вот, одну таблицу, где "нормальные" типы полей, я смог открыть, все замечательно. Но в другой есть поле типа, который называемый "COBOL Decimal Comp-3", длиной 3 байта... Слово Decimal явно говорит о том, что тип - числовой. Но числового типа длиной 3 байта в Delphi нет. Позволяет ли Дельфи как-то обойти такую ситуацию? Добавить свой вещественный тип?

А я столкнулась с таким типом данных Btrieve, как Money. Подбирала какой это тип данных в Делфи, подошел только Extended, т.е. если полю с типом Money я в описании структуры файла задаю Extended, то он записи выбирает нормально, НО в это поле попадают какие-то бешеные цифры абсолютно не соотв. действительности... Как с этим бороться не знаю :-(((
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33248270
bpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
3 раза ответил ничего не уходит.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33250614
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Len@
Extended подошел только потому что он занимает - 8 байт!, см. мой ответ на этот вопрос - это 15 значное десятичное в копейках (центах) со знаком.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33250615
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Money = decimal(15,2)
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33250873
bpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читайте help там все разжовано по приведению и преобразованию типов между delphi & PSQL (btrieve)
Используйте фирменные компоненты от Pervasive тогда вообще этих вопросов
не возникнет.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33250898
bpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В догонку

In addition to the Transactional and Relational interfaces, Pervasive.SQL provides methods to access data through OLE DB, Java (JDBC), ActiveX, ADO, and Pervasive Direct Access Components (PDAC) for Delphi and C++ Builder.

Сomplete sample application. Pervasive.SQL SDK includes a complete sample application designed to run a video rental store. Full sample code in Visual Basic, Delphi, Java, and C/C++ is supplied. Examples using ODBC, ActiveX RDO, third party controls, and direct API calls are shown.

Environments supported include Microsoft's Visual Studio (Visual Basic and Visual C++), Inprise (Delphi, C++ Builder, and JBuilder), and Symantec Visual Cafe. The SDK also supports C, C++, Java, and COBOL programming languages.
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33256625
Len@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BPAЧитайте help там все разжовано по приведению и преобразованию типов между delphi & PSQL (btrieve)
О Btrieve я впервые услышала около 2 месяцев назад и где-то месяц назад начала искать как можно к нему подобраться из Делфи...

Не подскажите о каком хелпе идет речь? В хелпах, статьях и т.д. что я читала ничего подобного не было...
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33257703
bpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Btrieve это старое название , сейчас оно зовется Pervasive SQL, последняя версия PSQL9.1

www.pervasive.com
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33258818
Len@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BPABtrieve это старое название , сейчас оно зовется Pervasive SQL, последняя версия PSQL9.1

Но у меня базы именно Btrieve 6.15
...
Рейтинг: 0 / 0
Взаимодействие с Btrieve из Delphi
    #33260174
bpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все версии поддерживаются сверху вниз.

Базы всех версий конвертируются снизу вверх.
--------------------------
Если у Вас нет описая базы(файлы *.ddf), но Вы знаете структуру записей таблиц, создать ее не составит большого труда, после этого будете иметь
полноценный SQL.
Если файлы *.ddf есть, то вообще ни какаих проблем -утилитку конвертации и все.
На сайте даже видеоролик есть о PSQL9 :)
-------------------------
Если не заморачиваться переходом на новые версии btrieve то
Для доступа из delphi к btrieve 6.15 и выше есть хорошая штука
Titan Database Interface™

http://www.reggatta.com/downloads.htm
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / Другие СУБД [игнор отключен] [закрыт для гостей] / Взаимодействие с Btrieve из Delphi
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]