PDA

View Full Version : مشکل در حجم زیاد بانک برای ذخیره عکس



aradsystem
شنبه 17 آذر 1386, 20:45 عصر
با سلام به همه دوستای خوب
من یه برنامه نوشتم برای بایگانی عکاسی.
از بانک اکسس برای ذخیره عکس استفاده کردم ولی بدلیل اینکه حجم هر عکس عکاسی متوسط 2 مگابایت می باشد حجم بانک نیز خیلی زیاد می شود و در موقع اجرای برنامه حدود نیم ساعت طول می کشه که فقط جدول باز بشه.
می خواهم که خود عکس در بانک ذخیره بشه من باید چیکار کنم. sql این مشکل رو برطرف می کنه؟
اگر راهنمایی بفرمایید ممنون میشم.

Cave_Man
شنبه 17 آذر 1386, 22:17 عصر
خب در موقع اجرای برنامه جدولت رو باز نکن یا فقط یکی دو رکوردش رو برای نمایش عکس باز کن

aradsystem
شنبه 17 آذر 1386, 22:37 عصر
این جواب شما صحیح نیست. بالاخره که باید جدول باز بشه که ازش چند تا رکورد رو بکشی بیرون.
همین باز شدن یه جدول چند گیگا بایتی کلی زمان میبره.
و اینکه من در صفحه اصلی می خواهم تو یه دیبی گرید همه رکورد ها رو نشون بدم.

ghabil
شنبه 17 آذر 1386, 23:00 عصر
خیر، شما یک کوئری بزنید و بجای Select * فقط فیلدهایی که لازم هست بیارید (فیلد عکس را نیارید) بعد هر موقع به خود عکس لازم بود با یک Select دیگه اطلاعات همون یک عکس رو بخونید ، چیزی هم طول نمیکشه اگر جایی کل جدول رو باز نکرده باشید.
ولی اصولا این حجم اطلاعات رو به SQL Server بدید بهتره.

aradsystem
شنبه 17 آذر 1386, 23:11 عصر
با تشکر از شما. برای ثبت رکورد جدید که بهید جدول باز باشه. حالا چیکار کنم؟
من از این کد برای ذخیره عکس در بانک اکسس استفاده کردم.
اگر لطف کنید کد insert با دستور sql در بانک sql رو بهم بدید ممنون میشم.
Image3.Picture.LoadFromFile(OpenDialog1.FileName);

data1.Pic.Append;
data1.Pic['sh_pic']:=strtoint(edit1.Text);
data1.Pic['name']:=edit2.Text;
data1.Pic['date1']:=edit3.Text;

Stream := Data1.Pic.CreateBlobStream(Data1.Pic.FieldByName(' pic'), bmWrite);
try
Image3.Picture.Graphic.SaveToStream(Stream);
finally
Stream.Free;
end;

data1.Pic.Post;

Bahmany
یک شنبه 18 آذر 1386, 09:46 صبح
سه پیشنهاد برای شما :
1- در آدرس دهی فایل برای این منظور استفاده کنید
یعنی موقعی که کاربر می خواهد عکسی رو داخل بانک اطلاعاتی قرار بدهد بجای اینکه اون عکس رو رداخل فایل بانک اطلاعاتی قرار بدهی اون رو کپی کن داخل یک پوشه پیش فرض و سپس آدرس فایل عکس رو در بان بگذار
2- از دو جدول برای این کار استفاده کن
به طوری که اولین جدول برای ذخیره سازی اطلاعات String ی عکس و جدول دوم نیز شامل لینکی از جدول اول برای ذخیره سازی فیلد عکس مورد نظر
3-
شما یک کوئری بزنید و بجای Select * فقط فیلدهایی که لازم هست بیارید (فیلد عکس را نیارید) بعد هر موقع به خود عکس لازم بود با یک Select دیگه اطلاعات همون یک عکس رو بخونید ، چیزی هم طول نمیکشه اگر جایی کل جدول رو باز نکرده باشید.
ولی اصولا این حجم اطلاعات رو به SQL Server بدید بهتره.

Touska
یک شنبه 18 آذر 1386, 12:08 عصر
اگر سیستم شما باید تحت شبکه کار کنه میشه Solution های بهتری هم داد.

موفق باشید :)

aradsystem
یک شنبه 18 آذر 1386, 19:44 عصر
درسته باید از یه select برای خوندن استفاده کنم که مجبور نباشم بجدول رو باز کنم.
ولی در موقع ثبت رکورد با دستورات append مربوط به جدول که باید بانک باز بشه.
با دستور sql نیاز نیست جدول باز بشه. حالا من کد ثبت رکورد با کمک جدول رو گذاشتم. دستور insert sql رو برای ثبت عکس به بانک می خواهم اگر لطف کنید دستورشو برام بنویسید.

ghabil
یک شنبه 18 آذر 1386, 20:59 عصر
با یک Insert و ساختن یک پارامتر از نوع ftBlob و ست کردن Stream فایل به مقدارش.
اما همین کدی هم که نوشتی اگر نمیخوای عوض کنی کافیه یک کوئری بزنی و Scheme جدول رو بگیری : مثلا بزنی Select * from Tablename where 1>2 اینطوری هیچ رکوردی نمیاد و اونوقت میتونی توی دیتاست خالی یک رکورد اضافه کنی. البته Optionی هم برای برای اجرای کوئری Scheme Only بود که الان Syntaxش یادم نمیاد.

aradsystem
یک شنبه 18 آذر 1386, 21:23 عصر
شرمنده من متوجه نشدم. من یه جا توی خمین سایت دستور insert sql رو برای عکس دیدم ولی پیداش نکردم . خیلی ساده و راحت بود.

اگه میشه مراحل کار و کدشو برام بزارو. ممنون میشم.

Bahmany
دوشنبه 19 آذر 1386, 07:32 صبح
اون جوری که بنده فهمیدم این دوستمون برای باز کردن جداول بانک اطلاعاتی از ADOTable استفاده می کنند و وقتی دستور Open رو می دهند تمام جدول cache می شود و بخاطر همین زمان زیادی رو می گیرد
بنده استفاده از روش زیر رو برای استفاده از بانک اطلاعاتتون پیشنهاد می کنیم
اول Connection مربوطه رو برقرار کنید بعد یک ADODataset فراخوانی کنید دستورات SQL را در آنجا وارد کنید سپس یک DataProvider ایجاد کنید و بعد یک ClientDataset و بوسیله DataProvider دو Dataset رو بهم متصل کرده و حالا می توانید تمامی Active ها رو true کنی
اگر خواستی می تونی از Datasource نیز استفاده کنی که باید به ClientDataset وصل بشه
اگر مشکلی بود بگو ادامه بدم

aradsystem
دوشنبه 19 آذر 1386, 10:31 صبح
اره من از adotable استفاده می کردم که حالا فهمید کارم اشتباه بوده.
الان فقط می خواهم با یک adoquery با یک connection کار کنم.

فقط دستور sql با پارامتر برای ذخیره عکس رو می خوام.
خواهش می کنم کمکم کنید خیلی وقته دنبالشم.

Bahmany
دوشنبه 19 آذر 1386, 11:29 صبح
خوب
1- یک عدد ADOConnection بساز و نام آن را بگذار ADOConnection1
2- یک عدد ADODataSet و نام اون ADODataSet1 بگذار
3- یک عدد DataSetProvider بساز و نام آن را بگذار DataSetProvider1
4- یک عدد ClientDataset بگذار و نام آن را ClientDataset1 بگذار
5- یک عدد Datasource بگذار و نام آن را Datasource1 بگذار
----------------------
1- در ADODataset1 دستورات مربوط به فراخوانی اطلاعاتت رو بنویس
2- در DataProvider1 خصوصیت Dataset رو به Dataset1 تخصیص بده
3- در ClientDataset1 خصوصیت ProviderName رو به DataProvider1 تخصیص بده
و سپس تمامی Active ها رو True کن
تمامی کارها رو می بایست با ClientDataset (اعم از Insert,Delete ,...) انجام بدی و همیشه بعد از انجام کارها ClientDataset1.ApplyUpdate(-1) رو اجرا کن تا تغییرات از حافظه منتقل بشند و همین
سوالی بود مطرح کنن داداش:

ghabil
دوشنبه 19 آذر 1386, 11:49 صبح
خوب
1- یک عدد ADOConnection بساز و نام آن را بگذار ADOConnection1
2- یک عدد ADODataSet و نام اون ADODataSet1 بگذار
3- یک عدد DataSetProvider بساز و نام آن را بگذار DataSetProvider1
4- یک عدد ClientDataset بگذار و نام آن را ClientDataset1 بگذار

تمامی کارها رو می بایست با ClientDataset (اعم از Insert,Delete ,...) انجام بدی و همیشه بعد از انجام کارها ClientDataset1.ApplyUpdate(-1) رو اجرا کن تا تغییرات از حافظه منتقل بشند و همین
سوالی بود مطرح کنن داداش:

من نمیدونم این 2 ،3 روزه من مشکلی پیدا کردم یا بچه های سایت با هم دیگه شوخیشون گرفته !! آخه این جواب چه ربطی داره؟ یکی پرسیده توی یک برنامه ساده دولایه چطوری با پارامتر فایل ذخیره کنم، داری راهنماییش میکنه برنامش رو ببره روی MIDAS و چند لایش بکنه !!!! سوالش رو هم جواب نمیدی؟!

بیا دادش این کدش تا کارت به سیستم پروگرمینگ نکشیده، فقط یکدونه ADOCommand بزار روی فرم اسمش رو هم ن گذاشتم AdoCmd:



with AdoCmd do
begin
Parameters.Clear;
CommandText := 'Insert Into TableName(Field1, FieldFile,...)' +
'Values(Valu1, :FileParam, ...)';
with Parameters.ParamByName('FileParam') do
begin
DataType := ftBytes;
LoadFromFile('FileName', ftBytes);
end;
Execute;
end;

Bahmany
دوشنبه 19 آذر 1386, 12:00 عصر
فکر کنم استفاده از این را بهترین راه باشه چون می تونید نه تنها از امکانات AdoDataset استفاده کرد بلکه می توان از امکانات Clientdataset نیز استفاده کرد البته درسته توی این پروژه زیاد نیز فرقی نمی کنه

ghabil
دوشنبه 19 آذر 1386, 12:50 عصر
ببین دو حالت داره ، یا تو درست فرق بین تکنولوژی های دو لایه و چند لایه و استفاده از DCOM رو نمیدونی و نمیدونی که کی باید از Dataprovider و CLIENTdataset استفاده کرد. یا اینکه کلا چند روزیه من با فارسی حرف زدن و متوجه شدن مشکل پیدا کردم.

aradsystem
دوشنبه 19 آذر 1386, 17:19 عصر
اقا خیلی خیلی ممنون لطف کردی مشکلم حل شد.
یه زحمت دیگه دارم.
من با adoquery هم این کدی که شما دادی تست کردم درست انجام داد.
وقتی یه رکورد از همین رکورد هایی که عکس داره رو select می کنم چجوری توی یک image نشون بدم؟

این جوری که قبول نمی کنه:
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from table1 whwre id="1"');
ADOQuery1.Open;

Image1.Picture:=ADOQuery1.Fields.Fields[0];

ghabil
دوشنبه 19 آذر 1386, 23:26 عصر
حالا چرا از DBIMage استفاده نمیکنی؟

aradsystem
سه شنبه 20 آذر 1386, 08:42 صبح
برای اینکه dbimage فقط bmp رو نشون میده ولی من jpg ذخیره می کنم.

Cave_Man
سه شنبه 20 آذر 1386, 09:17 صبح
برای اینکه dbimage فقط bmp رو نشون میده ولی من jpg ذخیره می کنم.
-------------------:متعجب:-------------------
من میتونم بهت اطمینان بدم که با خیال راحت میتونی از این ابزار بیشتر از چیزی که فکر میکنی بهره ببری

aradsystem
سه شنبه 20 آذر 1386, 11:12 صبح
خوب به منم توضیح بدین که چجوری میشه از این ابزار بیشتر بهره ببرم. همین فایل jpg رو از بانکم چجوری باهاش نشون بدم؟

الان نمیشه خروجی دستور select که یه فیلد عکس بر می گردونه رو توی یه image نشون بدم؟

ghabil
سه شنبه 20 آذر 1386, 12:57 عصر
توی Uses ها یونیت JPEG رو هم اضافه کن.

aradsystem
سه شنبه 20 آذر 1386, 18:40 عصر
علیرضا جان من امتحان کردم جواب نداد. dbimage فقط فایل bmp رو نشون میده.

نمیشه از دستور select که یه رکورد رو از جدول برداشته. اون فیلدی که عکس داره رو تو image نشون بدم؟

ghabil
چهارشنبه 21 آذر 1386, 11:16 صبح
بیا این کد دیگه هرچی باشه رو نشون میده:


var
AStream: TStream;
AJpg: TJPEGImage;
begin
AStream := ADODS.CreateBlobStream(ADODS.FieldByName('FieldNam e'), bmRead);
try
AJpg := TJPEGImage.Create;
try
AJpg.LoadFromStream(AStream);
Img.Picture(AJpg);
finally
AJpg.Free;
end
finally
AStream.Free;
end;

IMG مثلا همون IMageی هست که میخوای عکس توش نشون داده بشه.

aradsystem
چهارشنبه 21 آذر 1386, 11:28 صبح
علیرضا جان خیلی ممنون. مشکلم حل شد.
و همچنین از همه ی دوستان خوبم به خاطر راهنمایی کمک هایی که به من کردن خیلی خیلی متشکرم.

vcldeveloper
چهارشنبه 21 آذر 1386, 22:36 عصر
علیرضا جان خیلی ممنون. مشکلم حل شد.
و همچنین از همه ی دوستان خوبم به خاطر راهنمایی کمک هایی که به من کردن خیلی خیلی متشکرم.
برای تشکر از دکمه تشکر استفاده کنید. وقتی به جواب رسیدید، دکمه "حل شده" را کلیک کنید.