Нужно научиться писать базы в Delphi сетевые
4968
13
Хочу научится писать БД сетевые в Delphi, умею писать локальные при этом хорошо. Подскажите какую нибудь книгу умную именно для этого, или скиньте малюсенькую программу с открытым кодом на Delphi работающую с БД сетевыми на мыло temboMO@yandex.ru, дабы разобраться в коде, написанным обычным человеком, и если появяться вопросы то по возможности задать их. Заранее благодарен.
Valico
Ладно, тогда по другому скажу у меня есть программа, которая работает на двух компьютерах, в разных базах, вечером производтся обмен, т.е. с одной таблицы БД на одном компе данные перекидываются на другую таблицу другого компьютера. По идее бы хорошо сделать чтобы они работали одновременно на одной базе, тока не знаю как переделать и с чего взяться. Сейчас на обоих структура Paradox7 и BDE. Использую запросы SQL, для печати отчетов. Хочу чтоб не было глюков и ручных обменов расскажите как сделать или переделать.

П.С. Мне тоже кажется элементарно тайти и воплотить в жизнь какие то мелкие доделки в области где я знаю что то, все начианают тяжело. Мне так не просто ссылку а поподробнее. :umnik:
gorlan
Есть такие замечательные наборы компонентов, как Indy Servers и Indy Clients. Оттуда можно вытащить IdTCPServer и IdTCPClient. Вот с их помощью можно написать свой безглючный вариант сетевого взаимодействия двух баз, либо двух клиентов с одной базой. Да и вообще чего угодно. Эти компоненты позволяют гонять туда-сюда любые типы данных.
gorlan
Парадокс базы очень нежные, по сети будут слетать индексы при каждом чихе
Как вариант используй Access таблицы и работай с ними через ADO
gorlan
Хочу чтоб не было глюков и ручных обменов расскажите как сделать или переделать.
Если сделать с нуля, то использовать технологию клиент-сервер, к одной базе несколько человек... Хотя такое возможно и в файл-сервере на Парадоксе.
tpi
Если с нуля то какую именно технологию использовать, т.е. какие таблицы и как? Если так же в Paradox то как это построить, т.е. работу клиент сервер?
gorlan
Используйте например Firebird - бесплатный, шустрый клиент-сервер http://ibase.ru/firebird.htm .
Доступ из Делфи по IBX компонентам. Или купить FIB компонеты - http://www.devrace.com/ru/fibplus/index.php .
gorlan
Если с нуля то см то что уже советовали. Если надо в сеть засунуть то что уже есть (в локалке конечно) то я делал так.

Перво-наперво избавится от автоинкрементного типа в Paradox таблицах заменить тип поля на integer последние ID лучше держать в отдельной таблице, и вручную выбирать последний индекс и с ним добавлять в талицу следующий ID.
потом
На компе где база создать папку (например Program) в которую в кладем папки Base и BDE (с соответсвующим содержимым, BDE можно просто скопировать от туда где она установлена с дистриба Delphi).
Шарим эту папку.
И подключаем эту Program на всех трех компах сетевым диском с буквой скажем H:\
Регистируем эту BDE на всех трех машинах рег-файлом (пример рег-файла в атаче).
В BDEAdmin.exe создаем алиас с путем к базе через диск H:\

У меня все так и работает. Пошел таким путем когда оказалось, что надо локальную базу использовать в сетке.

ЗЫ Разумеется комп на котором лежит база и свич должны быть на УПСнике.
И регулярно производить переиндексацию. Тогда капризная связка BDE+Paradox практически не доставляет хлопот.
(там где я ставил эту прогу меня не беспокоили уже полгода )

ЗЫ2 Разумеется надо чуть переработать логику так чтобы она учитывала одновременную работу с таблицей нескольких пользователей.

Блин не могу приаттачить, взглюк какойто

пример регфайла

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine]
"DLLPATH"="H:\\BDE"
"RESOURCE"="0009"
"CONFIGFILE01"="H:\\BDE\\IDAPI32.CFG"
"UseCount"="1"
"SaveConfig"="WIN32"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT]
"VERSION"="4.0"
"LOCAL SHARE"="FALSE"
"MINBUFSIZE"="128"
"MAXBUFSIZE"="2048"
"LANGDRIVER"="DBWINUS0"
"MAXFILEHANDLES"="100"
"SYSFLAGS"="0"
"LOW MEMORY USAGE LIMIT"="32"
"AUTO ODBC"="FALSE"
"DEFAULT DRIVER"="PARADOX"
"MEMSIZE"="16"
"SHAREDMEMSIZE"="2048"
"SHAREDMEMLOCATION"=""
"DATA REPOSITORY"=""
"SQLQRYMODE"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\DATE]
"SEPARATOR"="/"
"MODE"="0"
"FOURDIGITYEAR"="FALSE"
"YEARBIASED"="TRUE"
"LEADINGZEROM"="FALSE"
"LEADINGZEROD"="FALSE"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\TIME]
"TWELVEHOUR"="TRUE"
"AMSTRING"="AM"
"PMSTRING"="PM"
"SECONDS"="TRUE"
"MILSECONDS"="FALSE"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\NUMBER]
"DECIMALSEPARATOR"="."
"THOUSANDSEPARATOR"=","
"DECIMALDIGITS"="2"
"LEADINGZERON"="TRUE"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\PARADOX]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\PARADOX\INIT]
"VERSION"="4.0"
"TYPE"="FILE"
"LANGDRIVER"="DBWINUS0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\PARADOX\TABLE CREATE]
"LEVEL"="7"
"BLOCK SIZE"="1024"
"FILL FACTOR"="95"
"STRICTINTEGRTY"="TRUE"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\INIT]
"VERSION"="4.0"
"TYPE"="FILE"
"LANGDRIVER"="db866ru0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\TABLE CREATE]
"LEVEL"="5"
"MDX BLOCK SIZE"="1024"
"MEMO FILE BLOCK SIZE"="1024"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSACCESS]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSACCESS\INIT]
"VERSION"="1.0"
"TYPE"="SERVER"
"DLL32"="IDDAO32.DLL"
"DRIVER FLAGS"=""
"TRACE MODE"="0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSACCESS\DB OPEN]
"DATABASE NAME"="DRIVE:/PATH/DATABASE.MDB"
"USER NAME"=""
"OPEN MODE"="READ/WRITE"
"LANGDRIVER"=""
"SYSTEM DATABASE"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSSQL]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSSQL\INIT]
"VERSION"="4.0"
"TYPE"="SERVER"
"DLL32"="SQLMSS32.DLL"
"VENDOR INIT"=""
"CONNECT TIMEOUT"="60"
"TIMEOUT"="300"
"DRIVER FLAGS"=""
"TRACE MODE"="0"
"MAX DBPROCESSES"="31"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSSQL\DB OPEN]
"DATABASE NAME"=""
"SERVER NAME"="PPCSERVER"
"USER NAME"="GUEST"
"OPEN MODE"="READ/WRITE"
"SCHEMA CACHE SIZE"="8"
"BLOB EDIT LOGGING"=""
"LANGDRIVER"="DBWINUS0"
"SQLQRYMODE"=""
"SQLPASSTHRU MODE"="SHARED AUTOCOMMIT"
"DATE MODE"="0"
"SCHEMA CACHE TIME"="-1"
"MAX QUERY TIME"="300"
"MAX ROWS"="-1"
"BATCH COUNT"="200"
"ENABLE SCHEMA CACHE"="FALSE"
"SCHEMA CACHE DIR"=""
"HOST NAME"=""
"APPLICATION NAME"=""
"NATIONAL LANG NAME"=""
"ENABLE BCD"="FALSE"
"TDS PACKET SIZE"="4096"
"BLOBS TO CACHE"="64"
"BLOB SIZE"="32"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\FOXPRO]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\FOXPRO\INIT]
"VERSION"="4.0"
"TYPE"="FILE"
"LANGDRIVER"="db866ru0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\FOXPRO\TABLE CREATE]
"LEVEL"="25"

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\REPOSITORIES]

[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\BLW32]
"BLAPIPATH"="H:\\BDE"
"LOCALE_LIB1"="H:\\BDE\\USA.BLL"
"LOCALE_LIB2"="H:\\BDE\\EUROPE.BLL"
"LOCALE_LIB3"="H:\\BDE\\OTHER.BLL"
"LOCALE_LIB4"="H:\\BDE\\CHARSET.BLL"
"LOCALE_LIB5"="H:\\BDE\\CEEUROPE.BLL"
"LOCALE_LIB6"="H:\\BDE\\FAREAST.BLL"
"LOCALE_LIB7"="H:\\BDE\\JAPAN.BLL"
Господин Уэф!
Перво-наперво избавится от автоинкрементного типа в Paradox таблицах заменить тип поля на integer последние ID лучше держать в отдельной таблице, и вручную выбирать последний индекс и с ним добавлять в талицу следующий ID.
потом
А можно это поподробнее? Как это сделать?
:dnknow:То что в реге написано я вручную научился делать.
gorlan
А можно это поподробнее? Как это сделать?
По подробнее, что именно? в чем вопрос? Подробнее только код.
Господин Уэф!
Если Вас не затруднит, то мне бы хотелось, если можно создайте одну табличку под парадокс, и сделайте, ее с этими изменениями, чтоб это можно было запустить с двух компов одновременно, меня интересует только код, и скрин шот Object inspector со стрелочкой в паинте нарисованой где меняются эти описанное значения.
gorlan
Во первых избавление от автоинкементного поля это не есть шаг в сторону сетевого использования программы построенной на обьектах TABLE1 которые обычно используются при написании локальной программы.
А всего лишь шаг в сторону увеличения надежности связки BDE+Paradox которая страдает падением основного индекса (и чудесными глюками вследствии этого) из=за перебоев питания компа, свича и т.д.
Для этого.
Берете вашу талицу в которой используется автоинкрементное поле. Открываете ее в Database Desktop (блин такое приходится обьяснять). И тип того поля, что у вас является уникальным-примари-основным ключем меняете с типа +(Autoincrement) на тип I (Long Integer). так же его делаете(оставляете) * (Примари индекс) в колонке Key. И сохраняете.
Теперь ваша таблица более устойчива к глюкам BDE.
Но при добавлении новой записи вам надо где-то брать номер этой новой записи, брать последнее значение из этой же таблицы увеличивать его на единицу и использовать полученное в качестве ID не советую, т.к. пока вы будете делать Table1.Insert эта же прога запущенная с другой машины может успеть сделать тоже самое и потом они обе попытаются вставить записи с одним и темже ID. Будет сообщение об ошибке, и вторая по времени запись не пройдет. (Хвала SQL, предать бы забвению весь этот бред ).
Блокировать таблицу для чтения-записи на время выемки последнего ID тоже не разумно т.к. имееется некое кол-во пользователей-программ которое в это время обязательно полезет в таблицу за данными.
Потому заводит некую таблицу с именем IDS_Table1 с одним единственным полем и одной единственной записью типа I (Long Integer) . в этой ячейке храним номер-последнийID таблицы TABLE1.
Когда пользователь просто меняет записи в TABLE1 нас это не касается, но когда он вставляет новую запись. Тогда наши действия таковы.
1.Блокируем IDS_TABLE1 на чтение/запись
2. Читаем последний ID
3. ID=ID+1 и кладем обратно.
4. Разблокируем IDS_TABLE1 на чтение/запись
5. Делаем вставку в TABLE1 с новым ID типа Table1.Insert(ID,......)

всЁ, кусок кода.

// получение номера следующей записи в TABLE1
repeat try
with MegaBase.IDS_TABLE1 do
begin
Refresh;
LockTable(ltReadLock);
LockTable(ltWriteLock);
num:=FieldValues['IDB'];
Edit;
FieldByName('IDB').AsInteger:=num+1;
Post;
flTry:=true;
end;
except on EDBEngineError do flTry:=false end;
until flTry;
// блокирование таблицы для записи для внесения изменений
repeat try
MegaBase.TABLE1.LockTable(ltWriteLock);
MegaBase.TABLE1.LockTable(ltReadLock);
flTry:=true
except on EDBEngineError do begin ShowMessage('Заблокированно');
flTry:=false end end;
until flTry;
with MegaBase.TABLE1 do
begin
CachedUpdates:=true;
Append;
FieldByName('TABLE_ID').AsInteger:=num;
FieldByName('FIO').Value:=TextFIO; //Здесь вставляются остальные данные
.................................
Post;
ApplyUpdates;
CachedUpdates:=false;
MegaBase.TABLE1.UnLockTable(ltReadLock);
MegaBase.TABLE1.UnLockTable(ltWriteLock);

end;
Тут я делаю не через Insert(), а через Append что сути не меняет.