Загрузка рисунков в БД

В процессе работы, достаточно часто возникает ситуация, когда работать приходится не только со стандартными типами данных в базе, но и с изображениями, звуками и другими неструктурированными объектами. При этом можно выделить два основных подхода к хранению подобной информации: 1. В БД хранится только путь к файлу, сам файл хранится на жестком диске. 2. Весь объект хранится в БД в сециальном поле с типом blob
В ряде серверов БД, например Micro$oft SQL 2008 появилась возможность объединить эти подходы, отчасти устранив ряд недостатков первого и второго. Но как обычно у гибридов, решив несколько старых проблем, приобретаем несколько новых. Впрочем речь не об этом.
В этой статье я хотел бы еще раз рассмотреть тему сохранения и извлечения неструктурированной информации на примере сервера БД Firebird и Borland Builder C++ 6. Что бы не усложнять материал, я буду рассматривать работу с рисунками (точнее фотографиями) в формате bmp и jpeg. И затем расскажу как можно расширить приведенную схему.
Итак для работы на нужно создать таблицу, которая содержит идентификатор и связанное с ним изображение. Делает это следующий скрипт:
[code]
CREATE TABLE PEOPLE_PHOTOS (
PEOPLE_ID INTEGER NOT NULL,
PEOPLE_PHOTO BLOB SUB_TYPE 0 SEGMENT SIZE 80 NOT NULL
);
[/code]
Для операции вставки (модификации) служит хранимая процедура:
[code]
CREATE OR ALTER PROCEDURE PEOPLE_PHOTO_INS (
people_id integer,
people_photo blob sub_type 0 segment size 80)
as
declare variable tmp_count integer = 0;
begin
/* Procedure Text */
select count(*) from people_photos where people_id = :people_id into :tmp_count;
if (:tmp_count = 1) then
begin
update people_photos set
people_photo = :people_photo where people_id = :people_id;
end
else if (:tmp_count = 0) then
begin
insert into people_photos (people_id, people_photo) values (:people_id, :people_photo);
end

suspend;
end

[/code]
Для выборки
[code]
CREATE OR ALTER PROCEDURE PEOPLE_PHOTO_SEL (
people_id integer)
returns (
people_photo blob sub_type 0 segment size 80)
as
begin
/* Procedure Text */
select people_photo from people_photos where people_id = :people_id into :people_photo;
suspend;
end

[/code]
Добавлению изображения в базу на стороне клиента служит следующий код:
[code]
//Заносим в параметр идентификатор
dmMain->fibPhotoIns->ParamByName("people_id")->Value = PeopleId;
TMemoryStream *pMS = new TMemoryStream;
Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap;
TJPEGImage *tmpImg = new TJPEGImage();
try{
//Загружаем изображение из файла и сохраняем его в поток
//если это JPEG
tmpImg->LoadFromFile(opOpen->FileName);
tmpImg->SaveToStream(pMS);

}catch(...){
//если нет - то обрабатываем исключение и загружаем битмеп
tmpBitmap->LoadFromFile(opOpen->FileName);
tmpBitmap->SaveToStream(pMS);

}
//Загружаем из потока в параметр и вызываем процедуру
dmMain->fibPhotoIns->ParamByName("people_photo")->LoadFromStream(pMS);
dmMain->fibPhotoIns->ExecProc();
delete pMS;
delete tmpBitmap;
delete tmpImg;
[/code]
Соотвественно получение изображения из базы в компонент TImage
[code]
imPhoto->Picture->Bitmap->CleanupInstance();
dmMain->fibPhoto->ParamByName("people_id")->Value = tmp;
dmMain->fibPhoto->Active = true;
TMemoryStream *pMS = (TMemoryStream*)dmMain->fibPhoto->CreateBlobStream(dmMain->fibPhoto->FieldByName("people_photo"),bmRead);
if(!pMS->Size){
dmMain->fibPhoto->Active = false;
return;
}
TJPEGImage *tmpImage = new TJPEGImage();
Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap;

try{
pMS->Position = 0;
tmpImage->LoadFromStream(pMS);
imPhoto->Picture->Bitmap->Assign(tmpImage);

}
catch(...){
pMS->Position = 0;
tmpBitmap->LoadFromStream(pMS);
imPhoto->Picture->Bitmap->Assign(tmpBitmap);

}
delete pMS;
delete tmpImage;
delete tmpBitmap;
dmMain->fibPhoto->Active = false;
[/code]
Обращаю ваше внимание – не забывайте устанавливать позицию потока в 0. Если вы получаете ошибку “JPEG error #52″ – значит либо вы забыли это сделать, либо ваш файл не JPEG.
Если в работе вам надо использовать более чем два типа файлов, то генерация исключений будет достаточно накладным решением. В таком случае нужно дополнительно вводить поле типа файла и обрабатывать его, оставляя исключения только для ошибок, либо же пытаться распознавать тип файла по сигнатуре.

Обсудить статью на форуме

Розкажи друзям

Share to Facebook
Share to Google Buzz
Share to Google Plus
Share to LiveJournal
Share to MyWorld
Share to Odnoklassniki
Share to Yandex
Ви можете залишити комментар, чи зробити посилання зі свого сайту.

Коментарів: 2 для “Загрузка рисунков в БД”

  1. Таисия коментує:

    А что такое БД?
    И с чем его едят?

  2. Константин коментує:

    [quote=Таисия]А что такое БД?
    И с чем его едят?[/quote]
    БД – база данных.

Залиште коментар

Programmed by Varkon Ltd