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

Для успешного кодирования необходимо включить typinfo в список используемых модулей. Код данного примера инвертирует логическое свойство Active набора данных, связанного с активным элементом управления при каждом нажатии пользователем клавиши ESC.

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
PropInfo: PPropInfo;
PropValue: TObject;
ds: TDataSource;
begin
if Key = VK_ESCAPE then
{ Основной код ниже }
try
ds := nil;
{ Проверяем, имеет ли компонент свойство DataSource }
PropInfo := GetPropInfo(ActiveControl.ClassInfo, ‘DataSource’);
if PropInfo <> nil then
{ Свойство компонента datasource типа class (например, TDataSource) }
if PropInfo^.PropType^.Kind = tkClass then
begin
PropValue := TObject(GetOrdProp(ActiveControl, PropInfo));
{ Создаем слепок найденного TDataSource }
ds := (PropValue as DB.TDataSource);
{ Используем dataset, связанный с datasource }
if not (ds.DataSet.State in dsEditModes) then
ds.DataSet.Active := not ds.DataSet.Active;
end;
except
on E: EInvalidCast do
ShowMessage(’Ошибка. Ожидался DataSource’);
end;
end;

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

Примерно через неделю после того, как программист впервые сталкивается с компонентом TStoredProc, предназначенным для вызова хранимых процедур БД, приходит понимание, что для работы с процедурами, которые не возвращают наборов данных (курсоров) лучше работать через один и тот же компонент, просто перенастраивая его. Итогом становится нагромождение однотипных строк кода, которые делают одно и то же. Сэкономлю вам еще одну неделю и предложу метод, который позволяет, как минимум, сократить количество строк, которые надо писать для вызова хранимых процедур.
Читать полностью…

{ **** UBPFD *********** by delphibase.endimus.com ****
>> TreeView - компонент для показа dataset в виде дерева с сохранением

Цель создания: необходимость быстрого выбора товара из справочника в виде дерева.
Компонент для визуализации дерева из таблицы. привязка к полям не ведется.
Ключевое поле находится в node.stateindex.

Использует 4 иконки для узлов и позиций, где 0-невыбранный узел,
1- выбранный узел, 2- невыбранный пункт, 3- выбранный пункт.

Необходимо выбрать datasource. вписать id, parentid.
Заполнение методом MRRefresh.
Сохранение в файл методом
MRPSaveToFile(ProgPath+’NameTree.tree’).
Загрузка из файла соответственно MRPLoadFromFile(ProgPath+’NameTree.tree’).
Кроме того поддерживаются метода последовательно поиска в обоих направлениях.

Зависимости: Windows, Messages, SysUtils, Classes, Controls, ComCtrls,DB,DBCtrls
Автор: Валентин, visor123@ukr.net, Днепропетровск
Copyright: Собственная разработка.
Дата: 9 апреля 2003 г.
***************************************************** }
Читать полностью…

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

Все это я делал раньше. Я не могу вам все это показать на развернутом примере, но я дам вам идею как сделать это. Вы должны иметь таблицу, осуществляющую взаимоотношение между людьми. Если на Peter работают Jane и Simon, вы должны иметь таблицу (RELATION) с этими двумя записями. Читать полностью…

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

Компания 2С: Программные комплексы для ведения двойной бухгалтерии.

В статье рассматривается работа с бинарными файлами из Delphi, а так же использование Object Pascal для управления записью, чтением и изменением собственных типов файлов.

Постановка задачи: Допустим, мне нужно в приложении Delphi сохранять некоторую информацию на диск. Мне не охото работать с текстовыми файлами, так как просмотр и обновление информации в них довольно муторное занятие. Преобладать будут операции записи и чтения, в то время как операции изменения и апдейта будут присутствовать в меньшей степени. Вся информация будет хранится в переопределённом типе данных Pascal Record. Итак, какой подход мне лучше всего использовать?

BDE плюс Paradox или Access, … спасибо, не надо…Не хотелось бы испытывать мороку с BDE. Использовать текстовые файлы ASCII ? Не пойдёт. Нужна хоть какая-то минимальная защита, а текстовые файлы “полностью видимы”. Оказывается, ответ на данный вопрос кроется в Delphi, а именно в непечатных файлах (или файлы некоторых типов/бинарные файлы).
Читать полностью…

Данный документ объясняет как выполнить запрос в фоновом режиме, используя класс TThread. Для получения общей информации о классе TThread, пожалуйста обратитесь к документации Borland и электронной справке. Для понимания данного документа вам необходимо иметь представление о том, как работать с компонентами для работы с базами данных, поставляемых в комплекте с Delphi 2.0.

Для осуществления потокового запроса необходимо выполнение двух требований. Во-первых, потоковый запрос должен находиться в своей собственной сессии с использованием отдельного компонента TSession. Следовательно, на вашей форме должен находиться компонент TSession, имя которого должно быть назначено свойству SessonName компонента TQuery, используемого для выполнения потокового запроса. Для каждого используемого в потоке компонента TQuery вы должны использовать отдельный компонент TSession. При использовании компонента TDataBase, для отдельного потокового запроса должен также использоваться отдельный TDataBase. Второе требование заключается в том, что компонент TQuery, используемый в потоке, не должен подключаться в контексте это потока к TDataSource. Это должно быть сделано в контексте первичного потока.
Читать полностью…

Автор: delphi | в 8:20 | Рубрики: ADO, Базы данных

По традиции, приложения Delphi использовали технологию BDE для доступа к данным. Но с появлением Delhi 5 появилась новая возможность - ADO.

С момента появления Delphi 5, который включает технологию ADOExpress ( она входит в Delphi Enterprise или продается как отдельная опция к Delphi Professional), программисты встретились с выбором: что использовать BDE или ADO для доступа к БД ? Типичным ответом на вопрос “Какую технологию Баз Данных использовать ?” будет - “Это зависит от …”
Читать полностью…

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

{ **** UBPFD *********** by delphibase.endimus.com ****
>> Запуск файлов хрянящихся в БД

Данный код реализует чтение из Бд строки где спрятан путь к файлу,
далее для удачного запуска “курсор” переместим в папку, от куда надо
запустить разбиваем строку на файл(для запуска) и на директорию
(для перемещения “курсора”).

Переброска “курсора” необходима для правильного запуска приложения.
Приложение может быть как под Windows, так и под Dos.

Зависимости: Windows, SysUtils
Автор: Дмитрий, ahmaev@mail.ru, ICQ:100716670, Пенза
Copyright: Дмитрий
Дата: 9 июля 2002 г.
***************************************************** }

procedure TForm1.dxfColorButton1Click(Sender: TObject);
var
s, files1, files: string;
dir, dir1: string;
apchar: array[0..500] of char;
i_s1: integer;
begin
{Находим нужную строку в Бд}
table1.locate(’kod_s’, treeview1.selected.parent.index + 1,
[loCaseInsensitive]);
table2.locate(’game’, treeview1.selected.Text, [loCaseInsensitive]);
{Перепишем из БД строки содержащие ссылки в переменные}
s := table2.fields[4].asstring;
k_s := length(table2.fields[4].asstring) + 1;
files := ”;
dir := ”;
repeat
i_s := i_s + 1;
k_s := k_s - 1;
{Поставим семафор, чтоб разделить путь и имя файла}
if s[k_s] = ‘\’ then
en := 1;
if s[k_s] <> ‘\’ then
if en = 0 then
files := files + s[k_s];
if en = 1 then
dir := dir + s[k_s];
until i_s = length(table2.fields[4].asstring);
{Переворачиваем считанное “путь до файла” и “имя файла”}
for i_s1 := length(files) downto 1 do
files1 := files1 + files[i_s1];
for i_s1 := length(dir) downto 1 do
dir1 := dir1 + dir[i_s1];
{Переводим курсор в папку откуда должна запустится программа}
chdir(dir1);
strpcopy(apchar, files1);
{Запускаем программу}
shellexecute(handle, ‘open’, apchar, 0, 0, SW_maximize);
end;

Часто приходиться решать те или иные задачи решение которых заложенны в информации о базе данных. Это состояние таблиц в базе, полей в таблице. Имена драйверов. Параметры алиасов, драйверов и.т.д, и.т.п. И тогда начинается самое интересное в деятельности программиста “как быть и что делать”. В этой статье не будет описанно какими методоми получить данные из базы. Концепция этой статьи заложенна в описании “физических аспектов” баз.
Читать полностью…

Словарь данных
СУБД должна обеспечивать функции словаря данных.
Сам словарь данных можно по праву считать базой данных
(но не пользовательской, а системной). Словарь содержит “данные о данных”
иногда называемые метаданными, т.е. определения других обьектов системы…

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

- Ты слишком много знал, - сказал Windows HardDisk-у.

uses BDE {в Delphi 1.x не помню, но вроде bdeprocs};

dbiSaveChanges

На Delphi 1.x (16bit) дополнительно вызовите эту процедуру:

procedure DropCache; assembler;
asm
mov ah,$0D
int $21
end;

Если база данных находится в той же директории, что и экзешник, то в качестве имени базы можно использовать .\ в поле DatabaseName в TTable

Билл Гейтс женился. Лег спать с молодой женой, а на следующее утро она говорит ему:
- Билли, теперь я знаю, почему твоя фирма называется Microsoft …

Следующая функция проверяет доступ к базе данных и выдает возможные причины, если доступ не удается осуществить. Функция возвращает значение True в случае успешной операции и False в противном случае.

function TBDEDirect.CheckDatabase: Boolean;
var
DS: TDataSource;
begin
Result := False;
DS := GetDataSource;
if DS = nil then
begin
MessageDlg(’Не установлена связь с элементом-источником данных.’+
‘Проверьте установку свойства DataSource.’,
mtError, [mbOK], 0);
Exit;
end;
if DS.DataSet = nil then
begin
MessageDlg(’Доступ к базе данных невозможен.’, mtError,
[mbOK], 0);
Exit;
end;
if TDBDataSet(DS.DataSet).Database = nil then
begin
MessageDlg(’Доступ к базе данных невозможен.’, mtError,
[mbOK], 0);
Exit;
end;
if TDBDataSet(DS.DataSet).Database.Handle = nil then
begin
MessageDlg(’Дескриптор (Handle) БД недоступен.’, mtError,
[mbOK], 0);
Exit;
end;
if DS.DataSet.Handle = nil then
begin
MessageDlg(’Дескриптор курсора (Cursor-Handle) недоступен.’, mtError,
[mbOK], 0);
Exit;
end;
Result := True;
end;

Вот такая конструкция проходит на DB2 2.1.2/NT и UDB5/NT…

CREATE DATABASE Efes2
USING CODESET 1251 TERRITORY RU
COLLATE USING IDENTITY;

Делается это при помощи dbiGetDatabaseDesc:

uses
BDE;

procedure ShowDatabaseDesc(DBName: string);
const
DescStr = ‘Driver Name: %s’#13#10′AliasName: %s’#13#10 +
‘Text: %s’#13#10′Physical Name/Path: %s’;
var
dbDes: DBDesc;
begin
dbiGetDatabaseDesc(PChar(DBName), @dbDes);
with dbDes do
ShowMessage(Format(DescStr, [szDbType, szName, szText, szPhyName]));
end;

Вы можете использовать вызов IDAPI dbiGetDatabaseDesc. Вот быстрая справка (не забудьте добавить DB в список используемых модулей):

var
pDatabase: DBDrsc:
begin
{ pAlias - PChar, содержащий имя псевдонима }
dbiGetDatabaseDesc ( pAlias, @pDatabase ) ;

Для получения дополнительной информации обратитесь к описанию свойства pDatabase.szDbType

Пpиходит пpогpамеp вечеpом домой весь в кpови и без pуки. Жена спpашивает:
- Что случилось доpогой???
Пpогpамеp:
- Да так, в кулеp засосало.

var
m: TMenuItem;
navidummy: TComponent;
………………………………………………….

procedure TMyForm.CreatePopUpMM(Sender: TObject);
begin

Navidummy.free;
Navidummy := TComponent.create(self);

while not NaviT.EOF do
begin
m := TMenuItem.create(navidummy);
II := II + 1;
with m do
begin
name := ‘MM’ + IntToStr(II);
caption := NaviT.Fieldbyname(’MyWHAT’).AsString;
tag := NaviT.Fieldbyname(’MyTAG’).AsInteger;
visible := True;
OnClick := NaviExec;
end;
MyMenuItem.add(m);
NaviT.Next;
end;
NaviT.Close;
end;

procedure TMyForm.NaviExec(Sender: TObject);
begin
{ Здесь я получаю то, что хочу ! }
What.text := (Sender as TMenuItem).Caption;
Key := (Sender as TMenuItem).Tag;
end;

Очень интересный и полезный вопрос!! Я сам так с ним до конца и не разобрался! Но я попробую систематизировать события, происходящие при запросе на завершение работы Windows:

Windows посылает сообщение WM_QUERYENDSESSION главным окнам всех запущенных приложений, при этом приложения должно сообщить свою готовность к завершению работы.
Если при этом хотя бы одно из приложений ответит отрицательно, Windows прерывает процесс завершения работы.

Delphi перехватывает это сообщение, и, в свою очередь, вызывает метод TForm.CloseQuery, (в главной форме, естественно), который генерирует событие OnCloseQuery, в обработчике которого можно указать на неготовность завершения приложения и отмены завершения работы Windows.

Если я правильно понимаю, если ваше приложение “не мешает” Windows завершить свою работу, Windows нормально НЕ завершает работу приложения, поскольку для этого нет необходимости, не нужно освобождать память, ресурсы и пр. Так, если это утверждение верно (это легко можно проверить, но я слишком ленив сейчас), то событие OnCloseQuery - ваш единственный шанс сохранения данных на диске. Я не думаю что эта логика слишком плоха, просто это одна из тех причуд Windows, которую нужно знать и пользоваться ею. Что может произойти в описанном выше сценарии: редактируемая в настоящий момент запись не будет отправлена (Post) в базу данных, но та же самая вещь может случиться и при нормальном завершении приложения.
При выходе из windows, вы вызываете WM_CLOSE api (или что-то типа этого) для каждого работающего в настоящий момент приложения. Программа закрывается точно таким же образом, как если бы вы щелкнули на кнопке закрытия или вызвали close из главной формы. Поэтому вам не нужно предпринимать никаких дополнительный действий, связанных с завершением работы с таблицами.

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

“Могу ли я при помощи объекта Tdatabase узнать с каким типом базы данных он связан?”

{uses должен включать в себя db, dbitypes, dbiprocs }
procedure TForm1.FormCreate(Sender: TObject);
var
rDB: DBDesc ;
begin
{ Первый аргумент DbiGetDatabaseDesc - имя псевдонима базы данных типа PChar }
Check(DbiGetDatabaseDesc(’IBLOCAL’, @rDB)) ;
{ член szDbType структуры DBDesc содержит информацию о типе
базы данных и имеет тип PChar }
ShowMessage( ‘Database имеет тип: ‘ + StrPas(rDB.szDbType) ) ;
{ Совет: Если вам просто необходимо узнать -
SQL server это или нет, используйте свойсто TDatabase
IsSQLBased }
end;

unit DdhDynDb;

interface

uses
Controls, Db, Forms, Classes, DbTables;

function ConvertClass(FieldClass: TFieldClass): TControlClass;

procedure NormalizeString(var S: string);

procedure ConnectDataFields(DbComp: TControl;
DataSource: TDataSource; FieldName: string);

function GenerateForm(StrList: TStringList;
SourceTable: TTable): TForm;

function GenerateSource(AForm: TForm;
FormName, UnitName: string): string;

implementation

uses
TypInfo, DbCtrls, SysUtils, StdCtrls, ExtCtrls, Windows;
Читать полностью…

Try
Tabl.Post;
Except
Begin
On EDatabaseError do
ShowMessage(’Не могу отправить данные (выполнить Post)’);
(Sender AS TDBEdit).SetFocus;
End; {Begin}
End, {Try}

Я осуществляю синтаксический разбор Error и вновь генерирую исключение (передаю по иерархии следующему обработчику объектов исключительных ситуаций), если я больше не хочу иметь с ним дела. Если использовать:

On E : EDatabaseError do…

то можно получить значение E.Error. Реально, имя свойства с текстом ошибки должно быть похоже на что-то типа E.Message (уточните в электронной справке).

On EDatabaseError do
begin
ShowMessage(’Не могу отправить данные’);
Edit1.setFocus;
end;

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

Программист ошибается дважды: первый раз - при рождении, а второй раз - при выборе профессии.

Цель данного доклада - оценить сегодняшние проблемы и тенденции развития технологий проектирования БД, а также, хотя бы отчасти - требования завтрашнего дня. Доклад может сыграть еще одну роль: задать набор актуальных требований, которые будут служить координатами для позиционирования конкретных частных методов и инструментов проектирования БД (отчасти также - средств их использования и управления ими), которые представляются в двух специальных секциях данной конференции.
Читать полностью…

Это простейший DLL, экспортирующий единственную функцию. Вызывающий ее оператор передает функции значение ключа и строку со значением. Функция открывает демонстрационную базу данных BIOLIFE, находит по ключу запись и добавляет строку после всех записей в поле Notes:

library Mydll;

uses
DBTables;

function Modify(Key: Double; const Info: string): Boolean; export;
var
Table: TTable;
Stream: TBlobStream;
begin
Table := TTable.Create(nil);
Table.DatabaseName := ‘D:\’;
Table.TableName := ‘BIOLIFE’;
Table.TableType := ttParadox;
Table.Open;
if Table.FindKey([Key]) then
begin
Result := True;
Table.Edit;
Stream := TBlobStream.Create(TMemoField(Table.FieldByName(’Notes’)),
bmReadWrite);
Stream.Seek(0, 2);
Stream.Write(Info[1], Length(Info));
Stream.Free;
Table.Post;
end
else
Result := False;
Table.Free;
end;

exports
Modify;

begin
end.

Вот как это можно вызвать из приложения:

function Modify(Key: Double; const Info: String): Boolean; far;
external ‘MYDLL’;

// Modify(90200, ‘Васек Трубачев’);

и это классно работает.

Поскольку в DLL вы используете BDE, изучите текущие замечания относительно его использования в файле README.TXT.

{ **** UBPFD *********** by delphibase.endimus.com ****
>> Процедура заполнения компонента TTreeView данными из TDataSet-совместимой выборки

Процедура заполнения компонента TTreeView данными из TDataSet-совместимой
выборки типа: idNode int, idParentNode int, cNodeName varchar, …

Важно: корневой узел дерева должен быть первой записью выборки.

Зависимости: Windows, SysUtils, DB, ComCtrls
Автор: Delirium, Master_BRAIN@beep.ru, ICQ:118395746, Москва
Copyright: Master BRAIN (Delirium)
Дата: 18 октября 2002 г.
***************************************************** }

procedure FillTree(Tree: TTreeView; Query: TDataSet; idNode, idParent,
cNodeName: string);
var
i: integer;
begin
// Корневой узел, должен быть первым в выборке Query
Query.First;
Tree.Items.Clear;
Tree.Items.AddObject(nil, Query.FieldByName(cNodeName).AsString,
Pointer(Query.FieldByName(idNode).asInteger));
Query.Next;
while not Query.Eof do
begin
i := 0;
while i < Tree.Items.Count do
if Tree.Items.Item[i].Data = Pointer(Query.FieldByName(idParent).asInteger)
then
begin
Tree.Items.AddChildObject(Tree.Items.Item[i],
Query.FieldByName(cNodeName).AsString,
Pointer(Query.FieldByName(idNode).asInteger));
break;
end
else
Inc(i);
Query.Next;
end;
end;
Пример использования:

FillTree(TreeView1, ADOQuery1, ‘idDoc’, ‘idParentDoc’, ‘cDocument’);

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

Если пpогpаммист в 09.00 утpа уже на pаботе, значит он ещё на pаботе…

dbMain.StartTransaction;
try
spAddOrder.ParamByName(’ORDER_NO’).AsInteger := OrderNo;
spAddOrder.ExecProc;
for i := 0 to PartList.Count - 1 do
begin
spReduceParts.ParamByName(’PART_NO’).AsInteger := PartRec(PartList.Objects[i]).PartNo;
spReduceParts.ParamByName(’NUM_SOLD’).AsInteger := PartRec(PartList.Objects[i]).NumSold;
end;
dbMain.Commit;
except
dbMain.RollBack;
raise;
end;

Сканирование версии структуры базы данных
——————————————————————————–

Спасибо за идеи, высказанные в группах новостей и присланные по электронной почте. Я думаю, что нашел лучшее решение.

Очевидно, BDE содержит номер версии структуры, по крайней мере для файлов Paradox. (Я не могу поручиться за dBase и другие форматы.) Всякий раз при изменении структуры (например, в Database Desktop) BDE увеличивает номер версии. Следующий модуль содержит функцию, которая возвращает версию структуры базы данных:
Читать полностью…

Я делал так (это кусок компонента):

if Picture.Graphic is TJPegImage then
begin
bs:=TBlobStream.Create(TBlobField(Field),bmWrite);
Picture.Graphic.SaveToStream(bs);
bs.Free;
end
else if Picture.Graphic is TBitmap then
begin
Jpg:=TJPegImage.Create;
Jpg.CompressionQuality:=…;
Jpg.PixelFormat:=…;
Jpg.Assign(Picture.Graphic);
Jpg.JPEGNeeded;
bs:=TBlobStream.Create(TBlobField(Field),bmWrite);
Jpg.SaveToStream(bs);
bs.Free;
Jpg.Free;
end
else
Field.Clear;

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

Данные (файлы) удаленной базы данных находятся на удаленном компьютере. (Следует обратить внимание, что каталоги удаленного компьютера не могут рассматриваться как сетевые диски.)

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

Серверная часть программы, работающая на удаленном компьютере, принимает запросы, выполняет их и пересылает данные клиентской программе. Запросы представляют собой команды, представленные на языке SQL (Structured Query Language) — языке структурированных запросов.

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

Транзакция — это некоторая последовательность действий, которая должна быть обязательно выполнена над данными перед тем, как они будут переданы. В случае обнаружения ошибки во время выполнения любого из действий вся последовательность действий, составляющая транзакцию, повторяется снова. Таким образом, механизм транзакций обеспечивает защиту от аппаратных сбоев. Он также обеспечивает возможность многопользовательского доступа к данным.

Разработка программы работы с удаленной базы данных — сложная и трудоемкая задача. Ее решение предполагает наличие у разработчика глубоких знаний и большого опыта разработки программного обеспечения. Поэтому в данной книге задача разработки удаленных баз данных не рассматривается.

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

procedure TForm1.BGetClick(Sender: TObject);
begin
with ProcGetInf do
begin
ParamByName(’pFam’).AsString := FamEdit.Text;
ParamByName(’pNam’).AsString := NamEdit.Text;
ParamByName(’pPar’).AsString := ParEdit.Text;
ExecProc;
if ParamByName(’pYear’).AsInteger = 0 then
MessageDlg(’В базе данных запись отсутствует’, mtError, [mbCancel], 0)
else
begin
SYear.Value := ParamByName(’pYear’).AsInteger;
CBDep.Text := ParamByName(’pDep’).AsString;
if ParamByName(’pSex’).AsString = ‘м’ then
RGSex.ItemIndex := 0
else
RGSex.ItemIndex := 1;
end;
end;
end; Читать полностью…