Данная статья не является каким-либо учебным пособием, а просто попыткой обобщить некий опыт, полученный в течение некоторого времени при использовании ADO.

Подвигло меня на написание этой статьи то обстоятельство, что когда я приступал к этой работе (я имею в виду использование ADO), я размещал свои вопросы во многих конференциях, а ответов на них не получено до сих пор и, более того, эти же вопросы стали задаваться по новой, а ответов на них как не было, так и нет. На некоторые из них я отвечал, а потом подумал, что не все будут просматривать конференцию целиком, да и когда все сведено в одном месте оно и лучше. Кроме того, толковой литературы по использованию ADO практически нет никакой. Например, мне не удалось найти в солидных по объему книгах г-на Архангельского необходимую мне информацию. Или еще пример - Microsoft Press ‘Справочник по OLE DB’. Здесь другой уклон - информации много, слишком много, а примеров никаких (но это вообще проблема справок от Microsoft - написано много, а примеров использования почти нет).
Читать полностью…

Автор: delphi | 14.12.2007 в 9:21 | Рубрики: Базы данных

В Local SQL для Paradox имеется ошибка, вместо вычитания происходит сложение даты с константой.

// Это добавляет единицу!
UPDATE SAMPLE.DB SET DT = DT - 1

// а данное выражение даст правильный результат:
UPDATE SAMPLE.DB SET DT = DT + (-1)

Вопрос:
- Почему в UNIX процедура входа называется “login”, а в Winodows - “logon”?
Ответ:
- Ну, знаете ли, это от позы зависит.

Как мне при соединении с таблицей Paradox устранить/”удовлетворить” окошко с требованием ввести пароль, защищающей таблицу?

Свойство компонента Table ACTIVE должно быть установлено в FALSE. (Если она активна прежде, чем вы ввели пароль, вы получите это окошко.) Затем поместите следующий код в обработчике события формы OnCreate:

session.AddPassword(’Мой секретный пароль’);
table1.active := true;

Забрали интернетчика в армию. На границе служить. Стоит он на посту. Вдруг - шаги.
- Пароль!!! …тишина
- Пароль!!!! …тишина
Программер снимает с плеча автомат… короткая очередь…
- User Anonymous Access Denied.

Автор: Александр Демский

Предупрежден - значит, вооружен. Берем Парадоксовскую табличку, паролим ее самым секретным паролем, бумажку с паролем сжигаем, а сам пароль забываем. Что теперь делать? Да ничего, просто открываем нашу табличку с одним из паролей: jIGGAe, nx66ppx, cupcdvum. Один, да подойдет. Не доверяйте своих секретов буржуям!

uses
Bde, SysUtils, dbtables, windows;

function StrToOem(const AnsiStr: string): string;
begin
SetLength(Result, Length(AnsiStr));
if Length(Result) 0 then
CharToOem(PChar(AnsiStr), PChar(Result));
end;

function TablePasswort(var Table: TTable; password: string): Boolean;
var
pTblDesc: pCRTblDesc;
hDb: hDBIDb;
begin
Result := False;
with Table do
begin
if Active and (not Exclusive) then Close;
if (not Exclusive) then Exclusive := True;
if (not Active) then Open;
hDB := DBHandle;
Close;
end;
GetMem(pTblDesc, SizeOf(CRTblDesc));
FillChar(pTblDesc^, SizeOf(CRTblDesc), 0);
with pTblDesc^ do
begin
StrPCopy(szTblName, StrToOem(Table.TableName));
szTblType := szParadox;
StrPCopy(szPassword, StrToOem(Password));
bPack := True;
bProtected := True;
end;
if DbiDoRestructure(hDb, 1, pTblDesc, nil, nil, nil, False) DBIERR_NONE then Exit;
if pTblDesc nil then FreeMem(pTblDesc, SizeOf(CRTblDesc));
Result := True;
end;

Автор: delphi | в 9:21 | Рубрики: Базы данных

Сообщение об ошибке: В файловой системе win95 существует ошибка, “микширующая” блокировку записи Paradox и механизм обновления. В хост-файлах Paradox в Windows 95 для работы нескольких пользователей измените следующие значения:

Select Control Panel
System (icon)
Performance (Tab)
File System (Button)
Troubleshooting (Tab)
“Disable New File Sharing and Locking Semantics” (щелкните) (нажмите OK)
(Выключить общий доступ к новым файлам и семантику блокировки)

Автор: delphi | в 9:21 | Рубрики: Базы данных

Что за магия при записи в поле Paradox Byte? По этому поводу в документации ничего не сказано.

Есть 2 пути получить доступ к данным в TBytesField.

Просто вызовите метод GetData, передавая ему указатель на буфер, где сам буфер должен иметь размер, достаточный для хранения данных:

procedure SetCheckBoxStates;
var
CBStates: array[1..13] of Byte;
begin
CBStateField.GetData(CBStates);
{ Здесь обрабатываем данные… }
end;

Для записи значений вы должны использовать SetData.

Используйте свойство Value, возвращающее вариантный массив байт (variant array of bytes):

procedure SetCheckBoxStates;
var
CBStates: Variant;
begin
CBStates := CBStateField.Value;
{ Здесь обрабатываем данные… }
end;

Первый метод, вероятно, для вас будет легче, поскольку вы сразу докапываетесь до уровня байт. Запись данных также получится сложнее, поскольку вам нужно будет работать с variant-методами типа VarArrayCreate и др.

Где-нибудь при закрытии главной формы выполните нижеследующие куски кода:

Для Delphi3 (при открытой таблице):

Table.FlushBuffers;

Для прочих:

Table.Open;
Check(dbiSaveChanges(Table.Handle));
Table.Close;

Чтобы сбросить кэш, можно еще после этого сделать:

asm
mov ah, $0D
int $21
end;

Автор: delphi | в 9:21 | Рубрики: Базы данных

Данная общая информация могла бы быть полезной при вычислении максимального размера записи для установки размера каждого блока.

Требования к предельным размерам типов полей таблицы Paradox

Данный список указывает количество байт каждого типа поля таблицы Paradox, занимаемое в структуре записи. Имейте в виду, что указанный размер занимает каждое поля в самом файле .DB, не во вспомогательных файлах типа .MB.
Читать полностью…

Автор: delphi | в 9:21 | Рубрики: Базы данных

Я пришел к тебе с дискетой, рассказать что сеть упала.

Может мне кто-нибудь помочь? Я получаю следующую ошибку приложения….Not initialized for accessing network files (не инициализировано для доступа к сетевым файлам).

Программа Borland BDE Install НЕ включает в себя автоматически драйвер для работы в сети для таблиц Paradox, если целевой компьютер подключен к сети. Ваш пользователь получит сообщение об ошибке, если путь никем не установлен. Программы третьих фирм, устанавливающие BDE, поступают точно так же (я использую WISE). Настройка сетевого каталога возможна программным путем из самой программы, или с помощью пользователя и утилиты BDEconfig.

При запуске приложения я разворачиваю предусмотренную Borland DLL “netdir.dll” (58K), загруженную из форума PdoxWin, получаю доступ к idapi.cfg и считываю значение сетевого каталога (netdir). Следующий код проверяет был ли установлен сетевой каталог, и, если не был, то он временно устанавливается для текущего сеанса пользователя.

{объявляем DLL функцию}
function getCFGNetDir: pchar; far; external ‘netdir’ index 4;

{проверяем и при необходимости восстанавливаем сетевой каталог}
procedure TmySplashForm.FormCreate(Sender: TObject);
var
theNetDir: pchar;
theChar: char;
begin
theChar := ‘:’
theNetDir := getCFGNetDir;
if (strscan(theNetDir, theChar) = nil) then
session.netfiledir := ‘C:\’;
end;

Автор: delphi | в 9:21 | Рубрики: Базы данных

Какой предел IDAPI для подключенных пользователей и размера файла для таблиц Paradox?

255 пользователей, максимальный размер таблицы по умолчанию от 128Мб до 4Гб, в зависимости от установки BLOCKSIZE в IDAPI.CFG во время создания таблицы. (максимальный размер = BLOCKSIZE x 64Mb).

Автор: delphi | в 9:21 | Рубрики: Базы данных

{ **** UBPFD *********** by delphibase.endimus.com ****
>> Упаковка таблиц Paradox & dBase

Процедура упаковки таблиц Paradox & dBase.
В процедуру передается TTable c любым состоянием свойства Active.
Состояние Active после выполнения процедуры остается предыдущим.
Процедура предусматривает отключение всех визуальных DbControls,
с последующим их подключением.

Зависимости: Bde, Db, DbTables
Автор: Александр, dbwork@kor.kes.ru, Кореновск
Copyright: Из исходного кода Database Workshop 4.12 (c)2002 Degisy Software
Дата: 23 мая 2002 г.
***************************************************** }
Читать полностью…

Пришёл программер как-то раз в ресторан, заказал себе отбивную. Берётся, значит, за дело, бац, а вилка с ножиком, аж соскальзывают с отбивной:
- Read only… - подумал программер.

Данный совет поможет вам разобраться в таком вопросе, как доступ к таблицам Paradox, расположенным на CD-ROM или диске, имеющем флаг “только для чтения”.

Механиз блокирования файлов Paradox требует наличие файла PDOXUSRS.LCK, осуществляющий логику работы блокировки. Данный файл обычно создается во время выполнения приложения и располагается в том же каталоге, где и таблицы. Тем не менее, в случае с CD-ROM, во время выполнения программы нет никакой возможности создать на нем описанный выше файл. Решение простое: мы создаем этот файл и помещаем его на CD-ROM во время его (CD) создания. Следующая простейшая программка позволит создать вам файл PDOXUSRS.LCK и поместить его в образ компакта для его последующего копирования на CD-ROM:
Читать полностью…

Автор: delphi | в 9:21 | Рубрики: Базы данных

Программисты не пишут нелогичных программ, бывают нелогичные пользователи.

Вы можете выполнить эту задачу, непосредственно обращаясь к BDE. Включите следующие модули в сецию Uses вашего модуля: DBIPROCS, DBIERRS, DBITYPES

Ниже приведена функция с именем ID, возвращающая сетевое имя входа:

function ID: string;
var
rslt: DBIResult;
szErrMsg: DBIMSG;
pszUserName: PChar;
begin
try
Result := ”;
pszUserName := nil;
GetMem(pszUserName, SizeOf(Char) * DBIMAXXBUSERNAMELEN);
rslt := DbiGetNetUserName(pszUserName);
if rslt = DBIERR_NONE then
Result := StrPas(pszUserName)
else
begin
DbiGetErrorString(rslt, szErrMsg);
raise Exception.Create(StrPas(szErrMsg));
end;
FreeMem(pszUserName, SizeOf(Char) * DBIMAXXBUSERNAMELEN);
pszUserName := nil;
except
on E: EOutOfMemory do
ShowMessage(’Ошибка. ‘ + E.Message);
on E: Exception do
ShowMessage(E.Message);
end;
if pszUserName <> nil then
FreeMem(pszUserName, SizeOf(Char) * DBIMAXXBUSERNAMELEN);
end;

Хотелось бы поделиться опытом использования баз данных Paradox в локальной сети. По большому счету, принципы распределенного и локального доступа к таблицам Paradox ничем не отличаются. Исключения составляют некоторые правила и рекомендации, которые изложены ниже…
Читать полностью…

Автор: delphi | в 9:21 | Рубрики: Базы данных

Вот код печати структуры таблицы Paradox, состряпанный на скорую руку. Предполагается, что компонент Table имеет имя Table1.

procedure TForm1.Button1Click(Sender: TObject);
const
FieldTypes: array[0..16] of string[10] = (’Unknown’, ‘String’, ‘Smallint’,
‘Integer’, ‘Word’, ‘Boolean’, ‘Float’, ‘Currency’, ‘BCD’, ‘Date’, ‘Time’,
‘DateTime’, ‘Bytes’, ‘VarBytes’, ‘Blob’, ‘Memo’, ‘Graphic’);
var
i, nX, nY, nHeight, nWidth: Integer;
rtxtMetric: TTextMetric;
s: array[0..3] of string[10];
begin
with Table1.FieldDefs, Printer do
begin
Update;
PrinterIndex := -1;
Title := ‘Структура ‘ + Table1.TableName;
BeginDoc;
nX := 0;
nY := 0;
WinProcs.GetTextMetrics(Canvas.Handle, rtxtMetric);
nHeight := rtxtMetric.tmHeight;
nWidth := rtxtMetric.tmAveCharWidth;
for i := 0 to Count - 1 do
begin
s[0] := IntToStr(Items[i].FieldNo) + #9;
s[1] := Items[i].Name + #9;
s[2] := FieldTypes[Ord(Items[i].DataType)] + #9;
s[3] := IntToStr(Items[i].Size);
Canvas.TextOut(nX, nY, s[0]);
Inc(nX, Length(s[0]) * nWidth);
Canvas.TextOut(nX, nY, s[1]);
Inc(nX, Length(s[1]) * nWidth);
Canvas.TextOut(nX, nY, s[2]);
Inc(nX, Length(s[2]) * nWidth);
Canvas.TextOut(nX, nY, s[3]);
nX := 0;
nY := i * nHeight;
end;
EndDoc;
end;
end;

Кто-нибудь знает как изменить месторасположение файла PDOXUSRS.NET во время выполнения программы?

DbiSetProp(hSessionHandle, sesNetFile, pchar(’c:\newdir’));

Для получения дескриптора сеанса, если вы используете сессию по умолчанию, необходимо вызвать DbiGetCurrSession .

Для dBase:

uses
DbiProcs;

with Table do
begin
OldState := Active;
Close;
Exclusive := True;
Open;

DbiPackTable(DBHandle, Handle, nil, nil, True);
{^ здесь можно добавить check()}

Close;
Exclusive := False;
Active := OldState;
{ при желании можно сохранить закладку }
end;
Читать полностью…

- Алло, техотдел? Я пароль набираю - а меня не пускают.
- Значит, правильно набирать надо.
- Я правильно набираю! Пять звездочек!

uses Bde, SysUtils, dbtables, windows;

function StrToOem(const AnsiStr: string): string;
begin
SetLength(Result, Length(AnsiStr));
if Length(Result) 0 then
CharToOem(PChar(AnsiStr), PChar(Result));
end;

function TablePasswort(var Table: TTable; password: string): Boolean;
var
pTblDesc: pCRTblDesc;
hDb: hDBIDb;
begin
Result := False;
with Table do
begin
if Active and (not Exclusive) then Close;
if (not Exclusive) then Exclusive := True;
if (not Active) then Open;
hDB := DBHandle;
Close;
end;
GetMem(pTblDesc, SizeOf(CRTblDesc));
FillChar(pTblDesc^, SizeOf(CRTblDesc), 0);
with pTblDesc^ do
begin
StrPCopy(szTblName, StrToOem(Table.TableName));
szTblType := szParadox;
StrPCopy(szPassword, StrToOem(Password));
bPack := True;
bProtected := True;
end;
if DbiDoRestructure(hDb, 1, pTblDesc, nil, nil, nil, False) DBIERR_NONE then Exit;
if pTblDesc nil then FreeMem(pTblDesc, SizeOf(CRTblDesc));
Result := True;
end;

{
The table component’s ACTIVE property must be set to FALSE
(If it is active before you have added the pasword, you will be prompted).
Then, put this code in the handler for the form’s OnCreate event:
}
Session.AddPassword(’My secret password’);
Table1.Active := True;

{
Once you close the table, you can remove the password with
RemovePassword(’My secret password’),
or you can remove all current passwords with RemoveAllPasswords.
(Note: This is for Paradox tables only.)
}

Я обнаружил, что открытый Data Desktop, даже без открытых объектов, может создавать “помехи”. Также мудрит открытая сессия Delphi, если вы запускаете собранное приложение вне IDE. Я допускаю, что если вы закрываете все объекты под DD, конфигурация BDE быстро себя не очистит. Наверное мне следовало бы запустить мое приложение пару недель спустя, но я реально предполагаю, что множество сеансов Paradox блокируют бедный BDE.

Пожалуйста запустите утилиту BDE Config, поставляемую с Delphi и с PdoxWin. Перейдите на страницу SYSTEM и проверьте, установлен ли параметр LOCAL SHARE. Если вы хотите, что несколько приложений имели доступ к данным Paradox, LOCAL SHARE должен быть установлен в TRUE (и должны быть загружены SHARE или VCACHE).

При этом вы должны принимать во внимание, что если вы хотите, чтобы “LOCAL SHARE = TRUE” все время работал правильно и надежно, вы должны также определить уникальные индивидуальные каталоги для всех приложений, использующих BDE для доступа к таблицам Paradox. В противном случае, “поведение по умолчанию” заставит BDE использовать текущий рабочий каталог как частный. И, как вы все догадываетесь, Pdox блокирует данный каталог, считая его “частной собственностью” и не допуская к табличкам остальных соперников . . . то-то, а вы говорите “блокируют бедный BDE”.

Автор: delphi | в 9:21 | Рубрики: Базы данных

var
Session: hTUses;
i: integer;
ErrorCode: word;
ResultCode: word;

procedure BdeError(ResultCode: Word);
begin
if ResultCode <> 0 then
raise Exception.CreateFmt(’BDE ошибка %x’, [ResultCode]);
end;

begin
try
BdeError(DbiInit(nil));
BdeError(TUInit(@Session));

for i := 1 to High(TableNames) do
begin
WriteLn(’Проверка ‘ + TableNames[i]);

ResultCode := TUVerifyTable(Session, @TableNames[i, 1], szPARADOX,
‘TABLERRS.DB’, nil, TU_Append_Errors, ErrorCode);
BdeError(ResultCode);

if ErrorCode = 0 then
WriteLn(’Успешно’)
else
WriteLn(’ОШИБКА! — Для информации смотри TABLERRS.DB!’);

WriteLn(”);
end;
finally
BdeError(TUExit(Session));
BdeError(DbiExit);
end;
end.

Таблицы Paradox имеют характеристику проверки целостности (Referential Integrity). Данная характеристика предотвращает добавление записей в дочернюю таблицу, для которых нет соответствующих записей в родительской таблице. Это также изменяет ключевое(ые) поле(я) в дочерней таблице при изменениях в соответствующем(их) ключевом(ых) поле(ях) родительской таблицы (обычно это называют каскадированным обновлением). Эти события происходят автоматически, и не требуют никакого вмешательства со стороны Delphi-приложений, использующих эти таблицы. Тем не менее, характеристика проверки целостности таблиц Paradox не работает с каскадированным удалением. То есть, Delphi не позволит вам удалять записи в родительской таблице при наличии существующих записей в дочерней таблице. Это могут сделать только дочерние записи “без родителей”, обходя проверку целостности. При попытке удаления такой родительской записи, Delphi сгенерит объект исключительной ситуации. Читать полностью…

var
db: TDatabase;
Desc: CRTblDesc;
begin
db := PriceTable.OpenDatabase;
FillChar( Desc, SizeOf( Desc ), #0 );
StrCopy( Desc.szTblName, PChar( PriceTable.TableName ) );
StrCopy( Desc.szTblType, szParadox );
StrCopy( Desc.szPassword, ‘password’ );
Desc.bProtected := TRUE;
Check( DbiDoRestructure( db.Handle, 1, @Desc, nil, nil, nil, FALSE ) );
end;

Автор: delphi | в 9:21 | Рубрики: Базы данных

Вот маленький кусочек кода для создания таблицы Paradox:

with TTable.create(self) do
begin
DatabaseName := ‘C:\temp’;
TableName := ‘FOO’;
TableType := ttParadox;
with FieldDefs do
begin
Add(’Age’, ftInteger, 0, True);
Add(’Name’, ftString, 25, False);
Add(’Weight’, ftFloat, 0, False);
end;
IndexDefs.Add(’MainIndex’, ‘IntField’, [ixPrimary, ixUnique]);
CreateTable;
end;

var
NeedNumber: Integer;


NeedNumber := Table.RecNo;
{сохранение номера нужной записи}

{код меняющий номе записи}

Table.RecNo := NeedNumber;
{востановление номера нужной записи}

Попробуйте одну вещь: заблокируйте файл перед попыткой открытия таблицы. Данная манипуляция перед открытием таблицы создаст файл PDOXUSER.LCK. После этого открытие таблиц будет более быстрым, особенно когда их открывают, закрывают и снова открывают. После окончания удалите блокировку файла.

Автор: admin | в 2:14 | Рубрики: Базы данных

dBASE и Paradox таблицы имеют в своем арсенале BLOB-поля, позволяющие хранить бинарные данные, в том числе bitmap-формат, отображаемый с помощью компонента TDBImage. В Database Desktop данный тип полей указан как Binary и Graphic (для dBASE и Paradox таблиц, соответственно). Тем не менее, процесс сохранения изображений в InterBase BLOB-полях и их использование в компонентах TDBImage не такой уж простой.

Таблицы InterBase не имеют простого типа BLOB-поля. Есть три варианта, или подтипа: тип 0, тип 1 и подтип, определенный пользователем. Типы 0 и 1 - “встроенные” типы. Тип 0 - BLOB-поля (тип по умолчанию) для хранения общих бинарных данных. Тип 1 - BLOB-поля для хранения текстовых BLOB-данных. Ни один из предопределенных типов не допускает автоматического извлечения данных изображения из BLOB-поля для его последующего отображения в компоненте TDBImage. BLOB-поля типа 0 могут использоваться для хранения данных bitmap-формата, но данные должны извлекаться и передаваться в объект типа TBitmap программным путем. Вот пример ручного извлечения данных изображения, хранящихся в BLOB-поле типа 0 (Table1BLOBField), и его показ в компоненте TImage (не предназначенным для работы с БД) :

Читать полностью…