الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مدة عملية الحفظ طويلة للغاية

بدأه صاحبة السمو في 13 أغسطس 2008 · 6 رد · 978 مشاهدة · في ADO.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

اخواني الكرام

السلام عليكم

اقوم باستيراد كمية بيانات من اكسيل (حوالي 5000 سطر)

الى داتا ست عندي

وبعد ذلك اقوم بحفظها الى الداتا بيس من نوع اكسس

المشكلة انو عملية الحفظ هدة تاخد وقت طويل للغاية ( اكثر من نصف ساعه ومع ذلك لسه لم ينتهي وقد قام بنقل ثلث البيانات تقريبا)

هل يوجد مشكلة في ذلك

علما انني استخدم الكود التالي

   Dim insertCommand As New OleDbCommand
			Dim time1 As DateTime
			sql = "insert into salama ([no1],[name],[date1],[time],[state]) values (?,?,?,?,?)"
			For i As Integer = 0 To ds.Tables("XLSData").Rows.Count - 1
				With insertCommand.Parameters
					.Add(New OleDbParameter("@no1", OleDbType.Integer))
					.Add(New OleDbParameter("@name", OleDbType.VarChar))
					.Add(New OleDbParameter("@date1", OleDbType.Date))
					.Add(New OleDbParameter("@time", OleDbType.Date))
					.Add(New OleDbParameter("@State", OleDbType.VarChar))

					.Item("@no1").Value = CInt(ds.Tables("XLSData").Rows(i).Item("No1").ToString)
					.Item("@name").Value = CStr(ds.Tables("XLSData").Rows(i).Item("Name").ToString)
					.Item("@date1").Value = CDate(CDate((ds.Tables("XLSData").Rows(i).Item("date1"))).ToString("dd/MM/yyyy"))
					time1 = CDate(CDate((ds.Tables("XLSData").Rows(i).Item("Time"))).ToString("hh:mm tt"))
					.Item("@time").Value = CDate(time1)
					.Item("@State").Value = CStr(ds.Tables("XLSData").Rows(i).Item("state").ToString)


				End With
				  Con.Open()
				insertCommand.Connection = Con
				insertCommand.CommandText = sql
				insertCommand.ExecuteNonQuery()
				Con.Close()
						Next

هل توجد طريقه اخرى لتقليل زمن عملية الحفظ

1145392391.gif
#2

أنت تقومين بعملية فتح و إغلاق للكونيكشن مع كل سطر. هذا يستهلك الكثير من الموارد. افتحي الكونيكشن مرة واحدة فقط في بداية العملية ثم أغلقيه بعد الإنتهاء من جميع السطور.

#3

شكرا اخي الكريم

ولكن انا بالفعل فكرت في هذه المشكلة من قبل وكان الكود الاصلي هو كما قلت بالضبط

وقمت بتغيره للتجربه وفي كلا الحالتين نفس النتجة

وبعد ذلك قمت بكتابة الوضوع

__

ولكن هل تعتقد اخي الكريم ان المشكلة هي ان البيانات قادمه من اكسيل وبذلك فانه قبل عملية الحفظ يقوم بتحويل كل سطر الى type المطلوب

وبالتالي فهذه العملية تاخد وقت طويل

1145392391.gif
#4

ربما. و لكن عليك أن تتذكري أن 5000 سطر كمية هائلة من البيانات بالنسبة للأكسس. ربما سيكون من الأفضل نقلها باستخدام أدوات الأكسس نفسها بدلاً من استخدام جمل الـinsert. لأن الأدوات التي تستخدمها الأكسس تقوم بعملية Bulk Insert و هي أسرع بكثير.

تعديل:

وجدت هذه الطريقة لعمل الـBulk Insert برمجياً.

http://www.codeproject.com/KB/database/Bul...sertAccess.aspx

تم تعديل هذه المشاركة بواسطة System Down في 13 أغسطس 2008 في 14:38

#5

شكرا اخي الكريم

ولكن لقد توصلت للحل الصحيح

وهو اضافة سطر بسيط وعمل الكود بشكل اسرع مما تتصور

14000 سطر في اقل من ربع دقيقه

 Dim insertCommand As New OleDbCommand
		Dim time1 As DateTime
		Con.Open()
		insertCommand.Connection = Con
		sql = "insert into salama ([no1],[name],[date1],[time],[state]) values (?,?,?,?,?)"
		For i As Integer = 0 To ds.Tables("XLSData").Rows.Count - 1
			With insertCommand.Parameters
				.Clear()
				.Add(New OleDbParameter("@no1", OleDbType.Integer))
				.Add(New OleDbParameter("@name", OleDbType.VarChar))
				.Add(New OleDbParameter("@date1", OleDbType.Date))
				.Add(New OleDbParameter("@time", OleDbType.Date))
				.Add(New OleDbParameter("@State", OleDbType.VarChar))

				.Item("@no1").Value = CInt(ds.Tables("XLSData").Rows(i).Item("No1").ToString)
				.Item("@name").Value = CStr(ds.Tables("XLSData").Rows(i).Item("Name").ToString)
				.Item("@date1").Value = CDate(CDate((ds.Tables("XLSData").Rows(i).Item("date1"))).ToString("dd/MM/yyyy"))
				time1 = CDate(CDate((ds.Tables("XLSData").Rows(i).Item("Time"))).ToString("hh:mm tt"))
				.Item("@time").Value = CDate(time1)
				.Item("@State").Value = CStr(ds.Tables("XLSData").Rows(i).Item("state").ToString)


			End With


			insertCommand.CommandText = sql
			insertCommand.ExecuteNonQuery()

		Next
		Con.Close()

وقد كتبت هذا الكود لتعم الفائده على الكل

1145392391.gif
#6

اظن ان الاختلاف الاهم في كود حضرتك هو اللي قالك عليه System Down انك تفتح الاتصال مرة واحد في الاول واغلاقه بعد ما تخلص خالص

بس ده غريبه بالنسبة لي، عشان كده انا لي سؤال اتمني حد يقلي عليه

هو استهلاك الموارد في وقت الاتصال والاغلاق ولا الوقت اللي بين الاتصال والاغلاق!!!؟ كنت دائما اقراء بعدم ابقاء الاتصال مفتوح بدون فائدة لذلك السبب! يعني المشكلة في وقت الاتصال بين الفتح والغلق

تم تعديل هذه المشاركة بواسطة الطائر التركي في 27 أغسطس 2008 في 01:43

شكرا

#7

عملية فتح إتصال هي عملية مكلفة من وجهة نظر قاعدة البيانات. لذا حاول التقليل من هذه العملية ما أمكن.

و لكن من جهة أخرى ترك الإتصال مفتوح دون استخدام يعني حجز أحد منافذ الإتصال الخاصة بقاعدة البيانات (عددها محدود) و هذا سئ بالذات في حال وجود أكثر من مستخدم.

مواضيع مشابهة