powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Другие СУБД [игнор отключен] [закрыт для гостей] / Взаимодействие с Btrieve из Delphi
25 сообщений из 30, страница 1 из 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
25 сообщений из 30, страница 1 из 2
Форумы / Другие СУБД [игнор отключен] [закрыт для гостей] / Взаимодействие с Btrieve из Delphi
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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