# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > VB.NET >  ذخیره عکس در دیتابس (VB.NET)

## جواد کاظمیان

سلام
من میخواهم در وی بی دات نت 2005 به وسیله ی کد یک عکس را در دیتابس اسکیول سرور ذخیره کنم چه کار کنم؟

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

Private Sub Save_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
        Dim ms As New MemoryStream
        Try
            PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
        Catch exc As Exception
            MsgBox("تصویر مناسب را انتخاب کنید")
        End Try

        Dim arrImage() As Byte = ms.GetBuffer
        Try
            CN.Open()
            Dim strSQL As String = "INSERT INTO Tab1(Picture)VALUES (@Picture)"
            Dim cmd As New SqlCommand(strSQL, CN)
            With cmd
                .Parameters.Add(New SqlParameter("@Picture", SqlDbType.Image)).Value = arrImage
            End With
            cmd.ExecuteNonQuery()
            CN.Close()
        Catch exc As Exception
        End Try
    End Sub

با تشکر

----------


## mostafa_leman

خوب عزیز من تو try catch گذاشتی . معلومه پیغام نمیده

----------


## mostafa_leman

از این کد استفاده کن :

       Try
            If Me.PictureBox1.Image Is Nothing Then
                Me.TableAdapter.Insert(Nothing)
            Else
                Dim ms As New MemoryStream
                PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
                Dim arrImage() As Byte = ms.GetBuffer
                ms.Close()
                Me.TbTableAdapter.Insert(arrImage)
            End If
        Catch ex As Exception
        End Try

----------


## shervin110uk

چرا اصلا ذخیره میکنی توی دیتابیس؟ حجم دیتابیس را خیلی میبره بالا.. بهترین کار اینه که بری و فایلهای را توی یک پوشه توی مسیر نصب برنامت کپی کنی و بعد آدرس ذخیره ی عکسهات را بریزی توی دیتابیس.... بعد هر موقع نیاز داشتی به صدا زدن عکس از آدرس ذخیرش استفاده کنی و توی سورس پیکچر باکست ازش استفاده کنی... این خیلی عاقلانه تره!

----------


## mostafa_leman

آقای شروین حجم دیتابیس بالا بره چه مشکلی پیش میاد؟

----------


## programmermp

سلام

اقای شروین

اقا مصطفی درست می گه اگر حجم دیتابیس بالا بره بهتر از اینه که اطلاعات امنیت نداشته

باشه 

در ضمن به مثال زیر یه نگاه بیاندازید برای ذخیره و بازیابی عکس هست 

بدرد بخوره

----------


## Alireza_Salehi

> آقای شروین حجم دیتابیس بالا بره چه مشکلی پیش میاد؟


همون طور که می دونید فیلد Image حداکثر در حدود 2 گیگا بایت گنجایش اطلاعات داره.

مزایای ذخیره تصویر در دیتابیس در مقابل ذخیره در فایل:
با توجه به این که تصاویر در کنار داده ها قرار دارند عملیات پشتیبان گیری ، به روزرسانی ، امنیت و یکپارچگی داده ها بهتر و ساده تر خواهد بود. ارتباط فایل های تصاویر با داده ها گم نمی شوندو ... در واقع لازم نیست کد نویسی اضافه برای حفظ جامعیت داده ها وامنیت انجام بدید.

معایب ذخیره تصویر در دیتابیس در مقابل ذخیره در فایل:

1.نکته ای که باید مد نظر داشته باشید اینه که این حجم از اطلاعات مستقیما در دیتابیس ذخیره نمی شوند و به قطعاتی در حدود 4 کیلوبایت شکسته می شوند و سپس ذخیره می شوند(مشابه یک لینک لیست در نظر بگیرید) واشاره گر هایی این قطعات را به هم متصل می کند.در هنگام اجرای دستور SELECT این قطعات به هم اسمبل می شوند!
در آزمایشات انجام شده سربار این روش بسیار بیشتر از استفاده از فایل محاسبه شده است!

2.دومین نکته این که این انتقال اطلاعات بین SQL Server و برنامه شما (تحت وب یا تحت ویندوز) از طریق پروتکل TDS و API های دسترسی داده انجام میشه که باز هم نسبت به ذخیره در فایل و (خواندن و نوشتن در فایل) کارایی کمتری دارد!

3.نکته سوم این که تقریبا غالب کامپوننت ها و کلاس های کار با تصاویر  برای کار با تصاویر درون فایل یا استریم ها بهینه شده اند و معمولا یک مرحله تبدیل علاوه بر موارد ذکر شده از دیتابیس به برنامه شما برای تبدیل اطلاعات باینری به عکس وجود داره که خوب باز هم ایجاد سربار اضافی می کنه!

4.با توجه به حجم زیاد این نوع داده ترافیک سرور نیز بالا میرود!


با توجه به موارد ذکر شده ذخیره تصویر در دیتابیس تنها در صورتی که حجم تصاویر بسیار کم بوده (مثلا تصویر افراد برای اطلاعات کارمندی وغیره- که در این مورد امنیت نقش مهمتری از کارایی دارد) و کمتر از 4k باشد منطقی به نظر می رسد و در موارد دیگر استفاده از فایل توصیه می شود. (من خودم در همین حد از دیتابیس برا ذخیره عکس استفاده می کنم)

در ضمن روشهایی برای تامین امنیت بدون دیتابیس هم وجود داره (بنابر این امنیت هم مسئله حادی به شمار نمیره)!
EFS , ACL ,DACL
روش های زیادی هم برای بهینه سازی ذخیره در دیتابیس وجود داره!


نکته آخر این که در این مورد زیاد بحث شده (تالا SQl Server رو در مورد Image جستجو کن) ولی بیشتر منابعی که بصورت علمی (سایت ها و افراد متخصص) قضیه رو بررسی کرده اند کارایی و سرعت فایل رو بیشتر محاسبه کرده اند.

برای اطلاعات بیشتر راهنمای SQL Server را جستجو کنید.

----------


## سعید112

باسلام و تشکر از مطالب مفیدتون
با استفاده از کدهای بالا تونستم یه عکسو به streamتبدیل کنم ولی وقتی دستور زیر می خواد اجرا بشه خطا میده .
me.sqldataadapter.update(me.dataset,"mytable")
ممنون میشم جواب بدید...

----------


## mostafa_leman

چه پیغامی میده؟

----------


## zerobit-ltd

> نکته ای که باید مد نظر داشته باشید اینه که این حجم از اطلاعات مستقیما در دیتابیس ذخیره نمی شوند و به قطعاتی در حدود 4 کیلوبایت شکسته می شوند و سپس ذخیره می شوند(مشابه یک لینک لیست در نظر بگیرید) واشاره گر هایی این قطعات را به هم متصل می کند.در هنگام اجرای دستور SELECT این قطعات به هم اسمبل می شوند!
> در آزمایشات انجام شده سربار این روش بسیار بیشتر از استفاده از فایل محاسبه شده است!


شما می تونید داده ها از نوع image رو به شرطی که حجمشون کوچک یا متوسط باشه و زیاد مورد استفاده قرار می گیرن، مستقیما داخل فیلد قرار بدید که به گفته microsoft بهترین روش برای چنین داده هایی، همینه.



> با توجه به حجم زیاد این نوع داده ترافیک سرور نیز بالا میرود!


برای انتقال داده های با حجم بالا، ترافیک شبکه بالا می ره. حالا فرقی نمی کنه که داده ها از database خونده بشن یا از هر جای دیگه از server.
آخرین نکته هم این هستش که خیلی کم پیش میاد یا اصلا پیش نمیاد که ما از کل 2GB  اندازه فیلد از نوع image برای ذخیره تصویر استفاده کنیم؛ نهایتا 5MB یا یه خورده بیشتر باشه (مگر این که بخوایم عکس یه ماموت با ابعاد واقعی رو توش ذخیره کنیم). ولی با توجه به این که دسترسی به داده های این نوع فیلد در حالت معمولی از طریق اشاره گرها صورت می گیره و با توجه به نکاتی که شما اشاره کردید (قرار گرفتن تصاویر در کنار داده ها، ساده شدن عملیات پشتیبان گیری و به روزرسانی، امنیت و یکپارچگی داده ها) بهتره که از ذخیره تصاویر در databse استفاده بشه.

----------


## Alireza_Salehi

تقریبا در اکثر موارد بحث روی کارایی ذخیره سازی عکس (یا هر نوع اطلاعات باینری) در دیتابیسه (در گوگل جستجو کنید)،در ضمن برای حجم کم همون طور که zerobit-ltd گفتند زیاد کارایی فرقی نمیکنه با توجه به مزایای دیگه این روش بهتره!

----------


## سعید112

سلامی دوباره
1 حجم عکسم 3 K.B  است
2 عین خطا اینه
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in system.data.dll
Additional information: System error.

----------


## سعید112

> چه پیغامی میده؟


با سلام . من که دیگه از بس ور رفتم خسته شدم
کسی جواب سوال منو میدونه خواهشا بگه
پیغام خطا رو قبلا نوشتم.امروز دو بار تونستم دستور update(me.sqldataadapter,"mytable")
رو انجام بدم .خطا هم نداد . خیلی خوبم توی پایگاه ذخیره شد ولی یی یی ی ی ی 
نمیدونم عیب از کجاست یهو قاطی کرد و روز از نو....  :خیلی عصبانی:

----------


## hamid_193

سلام به programmermp
(اقای صالحی )- من به تازگی شروع به کارکردن با vb.net شدم - یکی از مشکلاتی که داشتم این بود که می خواستم عکس را وارد sqlserver کنم - برنامه شما را اجرا کردم و قبل از اون پایگاه داده به همون اسم را ساختم و connection string را هم تغییر دادم . ولی موقعی که f5 را می زنم یک اشکال میگیره . روی خط 
PublicClass Form1 می ایسته و یک پنجره error میده که توش نوشته :
An unhandled exception of type 'System.ArgumentException' occurred in system.windows.forms.dll
Additional information: Cannot bind to property or column Photo on DataSource.

اگه امکان داره کمکم کنید که واقعا به این مسئله احتیاج دارم - قربان شما  :تشویق:

----------


## mostafa_leman

> با سلام . من که دیگه از بس ور رفتم خسته شدم
> کسی جواب سوال منو میدونه خواهشا بگه
> پیغام خطا رو قبلا نوشتم.امروز دو بار تونستم دستور update(me.sqldataadapter,"mytable")
> رو انجام بدم .خطا هم نداد . خیلی خوبم توی پایگاه ذخیره شد ولی یی یی ی ی ی 
> نمیدونم عیب از کجاست یهو قاطی کرد و روز از نو....


اگه یک بار ذخیره شده یعنی دستورتون مشکلی نداره ببینید کدوم قسمت برنامه تون مشکل داره؟

----------


## Barbodben

این قسمت اصلی برنامست، با این حال خود برنامه هم ضمیمه شده

Dim DS As New DataSet()
                SQLDataAdapter1.Fill(DS , "Flashcards")
                Dim TheTable As DataTable = DS.Tables(0)
                Dim aRow As DataRow = TheTable.NewRow()
                Dim fs As New FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Read)
                Dim MyData(fs.Length) As Byte
                fs.Read(MyData, 0, CInt(fs.Length))
                fs.Close()
                aRow("Picture") = MyData
                TheTable.Rows.Add(aRow)
                sqlDataAdapter1.Update(ds, "Flashcards")

----------


## __H2__

سلام
برای تاپیک دیگری نمونه کدی حاضر کرده بودم، گفتم شاید اینجا هم بزارم بد نباشد!
http://www.h02.ir/Download.aspx?File...InDatabase.zip

----------

