В этой статье я хотел бы рассказать как можно в своих приложениях БД использовать данные в Blob-полях. Этой статьей я хотел бы и закончить наш рассказ, про ADO технологию в Delphi для БД MS Access. Пойдем дальше и будем рассматривать другие БД и не много другие технологии. Так вот использование Blob-полей очень выгодно, нигде не потяряется нужный файл, но от них очень сильно растет размер нашей БД. Но это не беда, так как лучше уж размер БД вырастет, чем размер программы, да и еще с возможностью того, что файлы могут потеряться, это я про то, что если мы файлы будем хранить в какой-нибудь папке с программой.

Ну что приступим. Для начала создайте БД в MS Access и какую-нибудь таблицу, и в таблице обязательно должно быть поле с типом данных — Поле OLE-объекта. В этом поле и будут храниться наши файлы, а в точности картинки. Мы будем записывать и считывать картинки.

Как всегда сделаем подключение к нашей БД. Затем на OnCreate нашей формы активируем наш компонент запросов

procedure TForm1.FormCreate(Sender: TObject);
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM BlobTable');
ADOQuery1.Active:=True;
except
on e:Exception do
end;
end;

Не забудьте на нашу форму «положить» компонент TImage куда будет выводится наши картинки и TOpenDialog.

Для записи нашей картинки на событие кнопки — OnClick напишем следующее

procedure TForm1.Button2Click(Sender: TObject);
var
Blob:TMemoryStream;
begin
try
if OpenDialog1.Execute then
begin
ADOQuery1.Insert;
Blob:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName('blobs')),bmWrite);
Blob.LoadFromFile(OpenDialog1.FileName);
Blob.Free;
ADOQuery1.Post;
end;
except
on e:Exception do
end;
end;

Что здесь может быть непонятного, здесь у нас переменная памяти, в которую грузим нашу картинку, а затем при создании записываем ее в БД, указав идентификатор bmWrite, и необходимо сделать преобразование типов TBlobField, то есть мы указываем, что это точно поле с нашими двоичными данными. Запись вроде бы у меня прошла без ошибок, и если открыть нашу БД, то можно увидеть, что в поле, где сохраняли мы картинку написана такое — Двоичные данные. Это означает, что там что-то есть. Далее нам необходимо считать информацию из БД. Для этого на другую кнопку события OnClick пишем

procedure TForm1.Button1Click(Sender: TObject);
var
jpg:TJPEGImage;
Blob:TMemoryStream;
bmp:TBitmap;
begin
try
bmp:=TBitmap.Create;
jpg:=TJPEGImage.Create;
ADOQuery1.First;
Blob:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName('blobs')),bmRead);
jpg.LoadFromStream(Blob);
Image1.Picture.Assign(jpg);
jpg.Free;
Blob.Free;
bmp.Free;
except
on e:Exception do
begin
jpg.Free;
Blob.Free;
bmp.Free;
end;
end;
end;

Здесь у меня и TBitmap и TJpegImage, потому что я не знаю какой формат запишет в БД пользователь картинки. Вот для этого необходимо в БД сделать новое поле, где будет храниться наш формат данных, и при записи картинки записывать в это поле расширение нашей картинки, а при считывании проверять формат и в зависимости от него создавать ту или иную переменную. В данном случае я пробывал и с той, и с той у меня все получилось. Если будете использовать TJpegImage, то необходимо в Uses подключить модуль jpeg - для работы с jpg-изображениями. Также можно увидеть здесь, что я ставлю указатель на первую запись в БД с помощью First. Да просто мы записываем и в первой записи будет что-нибудь в любом случае, поэтому я ничего не стал придумывать, кидать грид на форму и получать картинки с выбранной строки, я получаю все время с первой строки, а уже усовершенствовать в ваших силах. Здесь также присутствует переменная памяти, в которую мы считываем данные, указав идентификатор bmRead, что означает, что мы считываем данные. Затем эту переменную загружаем в переменную изображения, ну а затем и в TImage. Как видите ничего сложного нету.

Этой статьей, я хотел бы подвести итоги с работой с Ado технологией в Delphi в БД MS Access. Далее мы рассмотрим как работать с Ado-технологией использую например MS Excel в качестве нашей БД.

Как записать картинки в БД другим способом мы еще рассмотрим, но тут технология ADO уже не причем. Таким способом можно записывать в любые БД картинки, даже не записывать, а формально хранить их там.

Кстати, хочу спросить, а Вы знаете преимущество газовых генераторов и газовых электростанций. Эти 2 прибора особенное подойдут у кого имеется свой коттедж или частный дом, которые смогут обеспечить электроэнергией, когда возникают перебои. Более подробно об их можно узнать на сайте — http://www.profmachina.ru, а также там сможете выбрать себе лучший вариант для вашего дома.

Исходники статьи скачать можно тут

Автор статьи - Andrey53

Метки: , , , , ,




К записи “Работа с ADO в Delphi. Часть 4” оставлено комментариев: 24.

  1. zerdalert:

    Огромное спасибо. Все изложено очень интересно и доступно для понимания даже для самых начинающих. Очень помогло.

  2. Dmitry:

    да уж….

    вы определяете переменную Blob как TMemoryStream, потом вы создаете не TMemoryStream, а уже TADOBlobStream, загружаете, и после этого переменную освобождаете, это уже ерунда какая то… и ЭТО работает???

    все это:
    ——
    Blob:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName(‘blobs’)),bmWrite);
    Blob.LoadFromFile(OpenDialog1.FileName);
    Blob.Free;
    ——-

    заменить на :

    TBLOBField(ADOQuery1.FieldByName(‘blobs’)).LoadFromFile(OpenDialog1.FileName);

    • Andrey53:

      Уважаемый, можно и так, способов много, я могу это сделать и с BlobStream, какие еще могут быть вопросы?

      • Dmitry:

        просто много лишних команд, и не понятен смысл объявления переменной, тем более когда она определяется в var одним типом, а в обработке создается другого типа.

        • Andrey53:

          TStream — класс потоков, у него есть различные дочерние объекты, классы, если существует потомок TADOBlobStream, значит это не лишнее, а он и используется для записи и чтения данных из БД blob-полей. Если я сделаю через TBlobStream, то я Вам угожу? TBlobStream — потомок, когда при объявлении и при создании будет одного типа, так Вас устроит?

          • ybrbnfHelp:

            Андрей Подскажи как у тебя изменить чтоб изменяло тока запись, а не добавляла новую, я уже многое перепробовал. Начал всё по мелочам разбирать и все равно сталкиваюсь с ошибками, мб я что то не дописываю, так уже кажется. Помоги )

          • Andrey53:

            ты имеешь ввиду редактировать запись? если да, то необходимо вместо Insert применить метод Edit

  3. Николай:

    А где взять компоненты TBitmap и TJpegImage

    • Andrey:

      это не компоненты, для использования TJpegImage необходимо подключить модуль jpeg в uses

  4. Влад:

    А как сделать чтобы считывало не с первой записи??

    • Andrey:

      Легко, можно установить курсор в нужное Вам место, с помощью процедуры Next, а можно использовать и другие процедуры, например FieldValues, можно узнать номер записи на которой стоит указатель и сделать потом запрос по идентификатору на выборку например

  5. Аноним:

    Всем привет! А можно в blob-поле добавлять текст, например через RichEdit и через такое же ,только в форме где DBGrid выводить ??? Я пробую след. код, а что то не выходит. Подскажите студенту?? )))
    Form1.ADOQuery1.Edit();
    TMemoryStream* strm = new TMemoryStream();
    RichEdit1.Lines.SaveToStream(strm);
    ((TGraphicField*)Form1.
    ADOQuery1.FieldByName(«othet»)).LoadFromStream(strm);
    Form1.RichEdit1.Lines = RichEdit1.Lines;
    delete strm;

  6. Евгений:

    Всем привет! А можно в blob-поле добавлять текст, например через RichEdit и через такое же ,только в форме где DBGrid выводить ??? Я пробую след. код, а что то не выходит. Подскажите студенту?? )))
    Form1.ADOQuery1.Edit();
    TMemoryStream* strm = new TMemoryStream();
    RichEdit1.Lines.SaveToStream(strm);
    ((TGraphicField*)Form1.
    ADOQuery1.FieldByName(«othet»)).LoadFromStream(strm);
    Form1.RichEdit1.Lines = RichEdit1.Lines;
    delete strm;

  7. Павел:

    А как из blob-поля открыть документ любого формата в соответствующем приложении?

    • Andrey:

      можно его вытащить из Blob поля сохранить временно, через ShellExecute например запустить, а потом удалить

  8. Андрей:

    А Я та думаю…. откуда у меня на форуме появился это быдло код… Хоть буду знать откуда ноги растут….

  9. Абай:

    А для того что бы не 1 строка только и в другие добавлять картинки какой код нужен?!
    я еще хотел спросить она не сохраняется картинка в базе что то. или я не так сделал что то.

  10. Здорова!можешь выложит статью как загружать и выгружать документ ворд из блоб полей… я пробовал несколько раз, рагрузить получилось, но чтение не получается…заранее спасибо…

  11. Александр:

    Спасибо за статью. Очень помогла.

  12. Володимир:

    Просьба. Использовал ваш код, с *.bmp сохраняется, а вот картинки jpg пишет что не bmp и возникает ошибка. Нельзя ли уточнить процес работи с jpeg. Мне нужно картинки просто сохранять в поле (потом через dbimage в программе все работает)

    procedure TForm3.Button1Click(Sender: TObject);
    var
    blob: TadoBlobStream;
    jpg: TJPEGImage;
    bmp: TBitmap;
    begin
    bmp := TBitmap.Create;
    jpg := TJPEGImage.Create;

    if OpenPictureDialog1.Execute then
    begin
    if not(unit4.DataModule4.ADOTable1.State in [dsEdit, dsInsert]) then
    unit4.DataModule4.ADOTable1.Edit;

    blob := TadoBlobStream.Create
    (TBlobField(unit4.DataModule4.ADOTable1.FieldByName(‘Піктограма’)
    ), bmWrite);
    blob.LoadFromFile(OpenPictureDialog1.FileName);
    blob.Free;
    jpg.Free;
    bmp.Free;

    unit4.DataModule4.ADOTable1.Post;
    end;

    end;

    Большое спасибо

Оставить комментарий

Вы можете использовать следующие теги:

*