|
|
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток! Нашел на этом сайте статью на тему подключения к бтривовским файлам из Дельфи. Для прямого подключения к базе с использованием Btrieve API необходимо расписать в программе структуру таблицы (добавляется тип record с полями, соответствующими названиям полей в таблице). При этом размеры и типы полей должны точно соответствовать (например, unsigned int, 4 byte (в таблице) -> longword (Дельфи)). Так вот, одну таблицу, где "нормальные" типы полей, я смог открыть, все замечательно. Но в другой есть поле типа, который называемый "COBOL Decimal Comp-3", длиной 3 байта... Слово Decimal явно говорит о том, что тип - числовой. Но числового типа длиной 3 байта в Delphi нет. Позволяет ли Дельфи как-то обойти такую ситуацию? Добавить свой вещественный тип? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.08.2005, 15:37 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Это упакованный с фиксированной десятичной точкой - каждая цифра 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). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 07:07 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Спасибо. Я, оказывается, выход нашел сразу, описал это поле как array [0..2] of char (значение этого поля меня не интересует). Но таблица не открывалась не по этой причине. Я выгружал таблицу docdep.dat (2Гб) (кто знает - это балансовые проводки в АБС-ке Diasoft Card). Так вот, открыть этот файл невозможно, если рядом с ним не лежит файл docdep.^01 (еще 400 метров :)). Кто-нибудь подскажет, что это за файл и нафига он нужен? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 08:51 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
В Btrieve таблицы не зависимы в том плане что нет запрета что-то читать отдельно - скорее всего ты натыкаешься на другие ограничения - например длину файла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 08:45 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
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); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 09:55 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Строку fillchar(DocdepRecord , SizeOf(DocdepRecord), #0); попробуй перенести выше - перед присвоением значений структуре DocdepRecord. Перед чтением установи индекс (должна быть специальная функция-команда что-то типа B_SET_INDEX) по которому будет поиск. Индексы не имеют имен, они нумеруются в порядке создания - вот только с 0 или 1 - точно не помню (кажется все же с 0). Функции передается номер индекса. Если запустить утилиту BUTIL -STAT <имя файла> получишь список индексов в порядке их создания. Или посмотреть в DDF файлах - номер там присутствует. B_GET_FIRST - чтение первой записи, если индекс не уникальный следующие записи читать B_GET_NEXT (должно быть както так) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 10:45 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Про строку в предыдущем посте я зря. Не могли бы вы послать на gol-sa@mail.ru файлики из Pervasive SQL SDK для Delphi. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 11:36 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
golsaПро строку в предыдущем посте я зря. Не могли бы вы послать на gol-sa@mail.ru файлики из Pervasive SQL SDK для Delphi. Издевается. Зайдите на pervasive.com там есть куча всяких библиотек для разработчиков чего только не упомнишь. А здесь если не ошибаюсь куча всяких ddf эдиторов. Pervasive это контора которая в свое время купила btrieve у новела ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 12:45 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Номер и структуру индекса я посмотрел как раз в DDF - это 0-й индекс (номер указан в предпоследнем параметре BTRVID). Причем DDF этот рабочий, т.е. верно отражает структуру таблицы (он используется давно для подключения через ODBC). "Перед чтением установи индекс (должна быть специальная функция-команда что-то типа B_SET_INDEX) по которому будет поиск. " Попробую покопаться еще, но навскидку в хелпе и *.pas файлах из SDK ничего подобного не вижу... Файлики сейчас Вам вышлю, возможно, Вы вспомните? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 14:22 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Я email написал неправильно - надо gol_sa@mail.ru Посмотри еще на RECORD для индекса - там может надо отменить выравнивание - PACKED RECORD. В строковых переменных вполне возможно надо расширять до полной длины пробелами. В зависимости от типа в BTRIEVE строковые переменные иногда приходится заменять на массивы типа CHAR (без байта длины в начале и без 0 в конце). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 07:21 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
У меня все строковые поля так и объявлены: array [0..n] of char. Packed попробовал убрать, не помогает. Процесс начинает напоминать танцы с бубном вокруг Btrieve. Вот, пока писал, пришла в голову мысль, что наверняка надо заполнять все поля в индексе? Я-то так и делаю, но в общем случае совсем неудобно получается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 08:38 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
При точном (B_GET_EQUAL) поиске надо заполнять все поля. Для команд B_GET_LESS (меньше) и B_GET_GREATER (больше) можно только по старшим полям индекса (любое кол-во полей с начала RECORDа без перерыва, остальные до конца RECORDа для стабильного результата затереть $0). Данные, которые передаются в BTRVID() больше никак не преобразуются, поэтому надо точно знать как их заполнять. Возьми любой 16-чный вьюер и рассмотри свой файл - найди там какую-нибудь запись. Вычлени поля индекса. Потом заполни данными свой RECORD и посмотри на его 16-ричный образ (можешь в файл записать). Образ должен один в один совпадать с полями индекса выбранными из записи. Учти в чистом BTRIEVE индекс может строится не по целым полям - просто там для индекса задается массив смешений от начала записи и длин (могут даже пересекаться!). Но к Pervasive SQL это не относится - в DDF индексы описываются только полями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 09:52 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Блин, у меня складывается впечатление, что 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('Не найдено'); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 12:14 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Только команды 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 12:57 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Если в том же вызове BTRVID B_GET_FIRST заменить на B_GET_GE (GREATER OR EQUAL), BTRVID возвращает 2 (IO Error). Ничего не понимаю: записи с crncode>840 точно есть (код валюты 978 - евро) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 15:18 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Тогда скорее всего структура индекса не соответствует DocdepIndex0. Или попробуй номер индекса = 1 (вдруг с 1 нумерация). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 09:11 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
golsa... попробуй номер индекса = 1 (вдруг с 1 нумерация). Эврика! Я-то ориентировался на DDF, считая, что там должна быть абсолютно точно расписана структура таблица, включая индексы. А на самом деле получается, что нулевой индекс в ДДФ-е пропущен. Т.е. в DDF на месте 0-го индекса стоит 1-ый, по которому я и пытался сделать поиск. Спасибо за помощь! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 17:54 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Все-таки проблемы не кончились. Когда в программе я нахожу по индексу первую запись, далее начинаю в цикле выбирать все записи, удовлетворяющие заданному условию. Так вот, после нескольких сот итераций (записей) снова вываливается статус=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; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 19:45 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Внешне код нормальный - погляди данные не длинее они заказаного в dataLen? (у Btrieve могут быть записи переменной длины), выведи значение dataLen после BTRVID() - он не меняется? может индекс битый? или сам файл? Или каким-то образом портятся данные в структуре PosBlock? В ней хранится информация о позиции текущей записи в файле (т.е. меняется при каждом BTRVID()), которая используется командой B_GET_NEXT. Сделай с помощью утилиты BUTIL (см. в каталоге BIN Pervasive) выгрузку данных (-SAVE), потом создание нового файла по шаблону (-CLONE) и загрузку в него данных (-LOAD). Индексы перестроятся, заодно полюбуешься на текстовый файл выгруженных данных. Попробуй отыскать запись, на которой сваливается программа. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2005, 06:31 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
При 2-ой ошибке нужно базу лечить однозначно. Пользуйся компонентами из PDAC Pervasive , ими можно как SQL запросами так и прямым доступом к таблице пользоваться, тем более что в PSQL v9 значичельно расширены возможности SQL, вплоть до встроенных функций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2005, 12:33 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
RAndrey Так вот, одну таблицу, где "нормальные" типы полей, я смог открыть, все замечательно. Но в другой есть поле типа, который называемый "COBOL Decimal Comp-3", длиной 3 байта... Слово Decimal явно говорит о том, что тип - числовой. Но числового типа длиной 3 байта в Delphi нет. Позволяет ли Дельфи как-то обойти такую ситуацию? Добавить свой вещественный тип? А я столкнулась с таким типом данных Btrieve, как Money. Подбирала какой это тип данных в Делфи, подошел только Extended, т.е. если полю с типом Money я в описании структуры файла задаю Extended, то он записи выбирает нормально, НО в это поле попадают какие-то бешеные цифры абсолютно не соотв. действительности... Как с этим бороться не знаю :-((( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2005, 12:41 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
3 раза ответил ничего не уходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2005, 13:31 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
2 Len@ Extended подошел только потому что он занимает - 8 байт!, см. мой ответ на этот вопрос - это 15 значное десятичное в копейках (центах) со знаком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2005, 06:56 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Money = decimal(15,2) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2005, 06:59 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Читайте help там все разжовано по приведению и преобразованию типов между delphi & PSQL (btrieve) Используйте фирменные компоненты от Pervasive тогда вообще этих вопросов не возникнет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2005, 10:19 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
В догонку 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2005, 10:27 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
BPAЧитайте help там все разжовано по приведению и преобразованию типов между delphi & PSQL (btrieve) О Btrieve я впервые услышала около 2 месяцев назад и где-то месяц назад начала искать как можно к нему подобраться из Делфи... Не подскажите о каком хелпе идет речь? В хелпах, статьях и т.д. что я читала ничего подобного не было... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2005, 15:02 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Btrieve это старое название , сейчас оно зовется Pervasive SQL, последняя версия PSQL9.1 www.pervasive.com ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2005, 08:39 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
BPABtrieve это старое название , сейчас оно зовется Pervasive SQL, последняя версия PSQL9.1 Но у меня базы именно Btrieve 6.15 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2005, 14:16 |
|
||
|
Взаимодействие с Btrieve из Delphi
|
|||
|---|---|---|---|
|
#18+
Все версии поддерживаются сверху вниз. Базы всех версий конвертируются снизу вверх. -------------------------- Если у Вас нет описая базы(файлы *.ddf), но Вы знаете структуру записей таблиц, создать ее не составит большого труда, после этого будете иметь полноценный SQL. Если файлы *.ddf есть, то вообще ни какаих проблем -утилитку конвертации и все. На сайте даже видеоролик есть о PSQL9 :) ------------------------- Если не заморачиваться переходом на новые версии btrieve то Для доступа из delphi к btrieve 6.15 и выше есть хорошая штука Titan Database Interface™ http://www.reggatta.com/downloads.htm ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2005, 08:17 |
|
||
|
|

start [/forum/topic.php?all=1&fid=56&tid=2016573]: |
0ms |
get settings: |
12ms |
get forum list: |
17ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
86ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
64ms |
get tp. blocked users: |
1ms |
| others: | 233ms |
| total: | 435ms |

| 0 / 0 |
