صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16
بسم الله الرحمن الرحيم
الغاية من الفكرة هي تعليمية بحته و مشاركات الاراء
الغالبية العظمى منا تملك كما كبيرا من الملعلومات في شتى الاختصاصات و انا اراهن بكل ما عندي الاغلب هنا هو محترف
و لديه من المعلومات ما يكفيه لان ينتج برنامج كامل متكامل لا يعيبه شيئ ؟؟؟؟
ما دخل هذا الكلام بالموضوع ؟؟
سبب هذا الكلام هو ان اغلب المبرمجين ليس فقط هنا بل بشكل عام اعتادوا على قراءة المواضيع و طرح الاسئلة و من ثم السلام
بمعنى نحن نقرأ المواضيع و نناقش و نكتب و نجيب لمجرد العادة (اي اعتدنا على ذلك) ترى السائل في كثير من الاحيان يملك الاجابة في داخله
لكنه لا يستطيع الوصول اليها ضمن طيات الدماغ يجرب و يجرب دون الوصول الى شيئ
السؤال من اين اتت الاجابة الى دماغ السائل بكل بساطة لقد قرأ في يوم من الايام موضوع او اجابة على نفس السؤال و لكن قراءة سريعة و السلام
الكثير من المقالات و الشروحات وضعت هنا و هناك لتاخذ بيدك الى الطريق الصحيح لكيفية استخدام تقنية ما و رغم قرائتنا لها و اعجابنا بها نحن نتجاهلها او نخاف منها مع اول تطبيق نقوم بصناعته و ذلك لقلة الخبرة في التعامل معها لذا نرى الاكواد قد ملئت النماذج من كل صنف و لون اجراء هنا و طريقة هناك و مصفوفة مكررة و معادة و متغيرات و كائنات ما زالت عالقة في انتظار ان تتخلص منها او تعيدها الى موطنها و البرنامج بطيئ و السلوك العام للبرنامج في اسوء حال و المعالج يركض و لا يلحق (الحمد لله ان سرع المعالجات كبيرة لتغطي على عيوبنا)
انا لا استثني نفسي طبعا لست دائما اعمل بالطريقة الصحيحة و السبب ان الفكرة تبدأ بسيطة و من ثم تكبر و تكبر و يصبح عدد الاكواد و حجم البرنامج عائق امام اعادة التفكير بالطريقة الصحيحة (ناتج عن الكسل طبعا) , لذا دائما و ابدا استخدم تحليل البرنامج و سجل كل خطواتك من اصغر شيئ لاكبر شيئ حتى لو استغرق ذلك منك شهر بكامله ؟؟؟
نعم حتى لو كان شهر لا تتسرع و تكتب الاكواد قبل ان تكتمل لديك على الاقل 90% من الافكار الخاصة بالبرنامج
بعد اكتمال الافكار لديك توجه و اختر الطريقة الصحيحة و المنهجية التي تستخدم في البرامج العالمية لكتابة فئاتك الخاصة و تنظيمها بشكل مثالي يختصر عليك عمليات التكرار و عمليات التصحيح في المستقبل كما يجعل مشروعك قابل للفهم من الغير
استخدم اي تقنية تراها مناسبة و تؤدي عملك و نصيحتي لا تنظر الى من يقول لك هذه تقنية قديمة و عفى عليها الدهر ما دامت التقنية التي تستخدمها تؤدي الغرض المنوط بها بشكل سليم. طبعا هذا ليس تشجيعا لك بالابتعاد عن التقنيات الحديثة بل اردت ان اوضح فكرة مفادها انك اذا لم تتعامل مع التقنية الحديثة من قبل و اردت استخدامها الان دون الخوض بها سابقا فاعرف انك ستفشل فشلا ذريعا.
نحن منذ اعوام كثيرة و نحن نركض وراء التقنيات و كلما ظهرت تقنية جديدة نقفز اليها و نحاول فهما و اتقانها و التعامل معها و ما تكاد تلم ببعض تفاصيلها حتى تظهر تقنية اخرى تلغي ما قبلها بنظر المبرمجين و ليس بنظر الشركات المنتجة عندها ستجد نفسك تلاحق سرابا و تكره الساعة التي تعلمت فيها البرمجة
الكثير من البرامج المعمولة بتقنيات قديمة ما زالت تستخدم و بكثرة و على مستوى عالمي و تؤدي عملها بشكل مذهل ؟؟؟
لذا لا يحبطك وجود تقنية حديثة من عدمها المهم في الامر ان تكون قادر على انتاج برنامج يؤدي المطلوب دون تذمر الشاري (الزبون) لان الزبون لا يهتم بالتقنية و لا المبرمج ايضا كل ما يهمه هو ان يعمل البرنامج و ينظم له عمله على اتم وجه.
يتبع.....
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16
تقديم لفكرة الكلاس
الغاية من تصميم هذا الكلاس هي للاتصال بـ SQL SERVER و من ثم الحصول على قواعد البيانات فيه
و التعامل مع قاعدة يحددها المبرمج و استجلاب جداولها او اي جدول تحدده انت
و من ثم استجلاب كل حقول الجدول او الحقول التي تحددها انت
ومن ثم عمل خصائص للحقول للتعامل معها من حيث الاضافة و الحذف و التعديل
ملاحظة: للذين يعملون مع برامج قواعد البيانات الخاصة بـ SQL SERVER الكل يعرف انني اذا اردت التعامل مع جدول ما من خلال برنامجي فان هناك العديد من الطرق منها
يحبذ البعض كتابة نص الاتصال الى القاعدة المحددة و من ثم كتابة جمل الاستعلام الخاصة به لجلب البيانات و من ثم التعامل مع كائنات لغة البرمجة التي تستقبل جمل استعلام SQL و من ثم تنفيذ هذه الجمل سواء كانت للاضافة او الحذف او التعديل
و البعض الاخر يعمل وفق تقنيات حديثة تقضي بعمل كائن مشابه للجدول او القاعدة (اقصد هنا تقنية التعامل مع لغة Linq) و يكون هذا الكائن بالاساس مشابه للاصل و لكن ضمن وحدة برمجية Class و ضمن هذا الكلاس يتم فرض هيكلية كاملة للقاعدة بكل ما تحويه من جداول و علاقات و حقول و اجراءات و وظائف و كل شيئ
و فق خصائص و طرق عندها تصبح هذه الوحدة تحتوي على كائنات معرفة بشكل مستقل ضمن اللغة (كما كان يحدث مع تقنية المعالج) عند هذه النقطة يمكن للمبرمج ان يستغني عن تقنية SQL و يتخاطب مع الكائنات الجديدة وفق لغة خاصة Linq اذا ان الوصول للكائنات الجديدة اصبح متاح و بشكل يسير كوننا قمنا بتعريفها ضمن فئات خاصة لذا ستجد ان محرر الكود سيدعم لك الوصول السريع لهذه الكائنات , كل هذا جميل و رائع لكن توقف لحظة ما الذي سيجري في الخلفية من سيتخاطب مع القاعدة و باي لغة ؟؟ لا تتعب نفسك اخي الكريم القاعدة لا تفهم الا لغة واحدة SQL الفرق الوحيد انك لن تحتاج الى تعلم SQL اذا ما كنت جاهلا بها سيتكفل محرك اللغة بالقيام باي عمليات خاصة مع القاعدة وفق SQL (عود على بدء).
لكي تتضح الامور اكثر سنقوم بالشرح وفق كل كود سنتعامل معه و ستتوفر لدينا الكثير من المعلومات الجيدة اذا كنت تنوي المتابعة معي و ستفهم آلية العمل بشكل مفصل يمكنك من توسيع الكلاس الذي سنقوم بعمله هنا لناسب حاجتك.
اولا قم بانشاء مشروع جديد من النوع Class Library
ثم سميه ServSite او اي اسم يعجبك هذا الاسم اخترته لان هناك جزئية تختص بالسيرفر ربما اذا توفر لدي الوقت ساتكلم عنه لاحقا
الان اصبح لديك Class جديد في المشروع اسمه ServSite
هذا الكلاس ساستخدمه للاتصال بالسيرفر لجلب السيرفرات المثبته على الجهاز و تاسيس الاتصال مع السيرفر المطلوب و من ثم جلب القواعد و تاسيس اتصال مع قاعدة محددة و استجلاب جداولها و التعامل مع جدول محدد فقط.
و سيكون لدي كلاس اخر في المشروع يختص بالعمليات على قواعد البيانات سيرث خصائص من الكلاس السابق ServSite
في البداية اذا كنت لم تتطلع على هذا الموضوع هنا الغزل مع SQL SERVER
انصحك بقرائته لانني قمت بشرحه بشكل مفصل لتعرف طريقة الاتصال باي سيرفرات مثبته على الجهاز
مادامت الاكواد تخدمني لعمل اتصال باي سيرفر و تاسيس اتصال معه و مع القواعد داخله لذا فليس من المنطقي ان اقوم بتجاهل هذه الميزة
و الاتجاه الى الطرق اليدوية للاتصال بالسيرفر سواء عن طريق الاعدادت او التعامل مع الملفات النصية
في بداية الكلاس و بعد قرائتك للموضوع السابق سنستورد بعض المراجع للتعامل معها
PHP كود :
Imports Microsoft.SqlServer.Management.Common Imports Microsoft.SqlServer.Management.Smo Imports Microsoft.Win32 Imports System.Data.SqlClient Public Class ServSite
و ساعرف مجموع من الكائنات التي ساحتاجها ان وضعت الشرح في داخل الكود مع كل كائن
PHP كود :
''' <summary> ''' متغير من النوع سيرفر ''' نستخدمه للتعامل مع السيرفر ''' </summary> ''' <remarks></remarks> Protected Shared Srv As New Server
''' <summary> ''' متغير من النوع اتصالات السيرفر ''' نستخدمه لتمرير اتصال للسيرفر ''' </summary> ''' <remarks></remarks> Protected Shared srvcon As New ServerConnection
''' <summary> ''' متغير من النوع اتصالات السيكوال نستخدمه للاتصال بقاعدة البيانات ''' </summary> ''' <remarks></remarks> Protected Shared SqlConnection As New SqlConnection
''' <summary> ''' مصفوفة لتخزين اسماء السيرفرات ''' </summary> ''' <remarks></remarks> Protected Shared SrvNameArray() As String
''' <summary> ''' مصفوفة لتخزين اسماء قواعد البيانات ''' نستثني قواعد بيانات النظام ''' </summary> ''' <remarks></remarks> Protected Shared srvdbnames() As String
''' <summary> ''' مصفوفة لتخزين اسماء الجداول في القاعدة المحددة ''' </summary> ''' <remarks></remarks> Protected Shared TablesSrvDbs() As String
''' <summary> ''' متغير نصي نخزن فيه اسم القاعدة المحددة ''' </summary> ''' <remarks></remarks> Protected Shared SqlDbName As String
''' <summary> ''' متغير نصي نخزن فيه نص الاتصال مع قاعدة البيانات ''' </summary> ''' <remarks></remarks> Protected Shared _SqlConnectionString As String
بالنسبة للجزئية الخاصة XML Tags for Documentation الظاهرة ضمن الاكود اذا ما لم تتعامل معها سابقا
ساقول لك بانها طريقة جميلة للتعليق على الوظائف و معرفة الغرض منها اثناء اعادة استخدامها .
الفائدة منها تاتي عند تعريفك للكائن في وحدة برمجية جديدة ستاتيك المعلومات المرافقة للكائن و التي كنت قد كتبتها سابقا تمام كما يحصل مع اي كائنات ضمن اللغة عندما يقف عليها المؤشر
الجميل فيها ايضا يمكنك تمرير معلومات تفصيلية عن البارمترات التي تريد تمريرها كذلك وضع ملاحظات مفصلة كما تحب و كلها ضمن Tag Xml واحد
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16
الان ناتي الى الاستفادة من الكائنات التي عرفناها مسبقا و نحول ملئها بالمعومات المفيدة
اولا لنحصل السيرفرات المثبته بالجهاز و فق الاجراء التالي
PHP كود :
''' <summary> ''' اجراء يقوم بالبحث عن السيرفرات المثبتة على الجهاز ''' و اضافتها الى مصفوفة السيرفرات ويعيد نص اتصال مع السيرفر ''' </summary> ''' <returns>يعود بقيمة نصية تمثل اسم السيرفر الاخير</returns> ''' <remarks>بامكانك استخدام مربع نص او قائمة لاستقبال المخرجات</remarks> Private Shared Function LoadServ() As String Dim Machine As String = Nothing Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Microsoft SQL Server") Dim instances As [String]() = DirectCast(rk.GetValue("InstalledInstances"), [String]()) If instances.Length > 0 Then For Each element As [String] In instances If element = "MSSQLSERVER" Then Machine = (System.Environment.MachineName) ReDim SrvNameArray(instances.Length - 1) instances.CopyTo(SrvNameArray, 0) Else Machine = (System.Environment.MachineName + "\" + element) ReDim SrvNameArray(instances.Length - 1) instances.CopyTo(SrvNameArray, 0)
End If Next
End If srvcon = New ServerConnection(Machine) Srv = New Server(srvcon) Return Machine End Function
هذا الاجراء موجود في الموضوع الذي اشرت اليه في الاعلى لمن يعاني من مشكلة فيه كما حصل مع الاخ عمر مكاوي فليستخدم كود الاخ عمر
و الكودان يعملان بشكل جيد
و الوظيفة من الاجراء السابق مشروحة ضمن التعليقات بالكود السابق و مختصرها جلب السيرفرات في الجهاز و وضعها في مصفوفة السيرفرات التي انشأناها سابقا
بعد ان توفرنا على السيرفر اصبح بامكاننا الحصول على قواعد البيانات بداخله و اضافتها الى مصفوفة قواعد البيانات لدينا
PHP كود :
''' <summary> ''' اجراء يقوم بتحميل قواعد البيانات في السيرفر المحدد ''' واضافتها الى مصفوفة القواعد ''' </summary> ''' <remarks></remarks> Private Shared Sub loaddbnames() Dim db As New Database Dim j As Integer = 0 For i = 0 To Srv.Databases.Count - 1 If Not Srv.Databases(i).IsSystemObject And Not ((Srv.Databases(i).Name = "")) Then ReDim Preserve srvdbnames(j) db.Name = Srv.Databases(i).Name srvdbnames.SetValue(db.Name, j) j += 1 End If Next End Sub
و كذلك ايضا تحميل الجداول في القاعدة المحددة الى مصفوفة الجداول .
PHP كود :
''' <summary> ''' اجراء يقوم بتحميل جداول القاعدة المحددة ''' و اضافتها الى مصفوفة الجداول ''' </summary> ''' <remarks></remarks> Private Shared Sub LoadTablenames()
If Not (SqlDbName Is Nothing) Or SqlDbName = "" Then Dim Dbs As Database = Srv.Databases(SqlDbName) ReDim TablesSrvDbs(Dbs.Tables.Count) For i = 0 To Dbs.Tables.Count - 1 If Not Dbs.Tables(i).IsSystemObject Then TablesSrvDbs.SetValue(Dbs.Tables(i).Name, i) End If Next End If
End Sub
الاجراء الخاص بتاسيس اتصال مع القاعدة المحددة مشروح بالتفصيل ضمن الكود
PHP كود :
''' <summary> ''' اجراء يقوم بتاسيس الاتصال مع القاعدة المحددة ''' و يحتاج الى بارميتر نصي يمثل اسم القاعدة ''' </summary> ''' <param name="Dbname">اسم قاعدة البيانات كنص</param> ''' <returns>يعود بقيمة نصية تمثل نص الاتصال</returns> ''' <remarks></remarks> Public Shared Function SetConnectionString_ForDb(ByVal Dbname As String) As String 'فحص طول مصفوفة السيرفرات If SrvNameArray.Length <= 0 Then LoadServ() End If 'فحص طول مصفوفة القواعد If srvdbnames.Length <= 0 Then loaddbnames() End If
'التاكد من وجود سيرفرات على الجهاز من خلال مصفوفة السيرفرات If srvdbnames.Length <= 0 Then Return MsgBox("تاكد من وجود سيرفرات على الجهاز", , "From SetConnectionString_ForDb") Exit Function End If 'التاكد من وجود قواعد على السيرفر من خلال مصفوفة القواعد If srvdbnames.Length <= 0 Then Return MsgBox("تاكد من وجود قواعد على السيرفر", , "From SetConnectionString_ForDb") Exit Function End If 'الحصول على اسم اخر سيرفر Dim PcName As String = LoadServ() 'حلقة لفحص وجود القاعدة المحددةفي مصفوفة القواعد 'ثم اسنادها الى المتغير العام الذي يمثل اسم القاعدة 'ثم تحميل الجداول الموجودة في القاعدة الى مصفوفة الجداول 'و العودة بنص الاتصال مع القاعدة المحددة For i As Integer = 0 To srvdbnames.Length - 1 If (Dbname = srvdbnames(i)) Then SqlDbName = Dbname LoadTablenames() Return "Data Source=" & PcName & ";" & "Database=" & SqlDbName & ";" _ & "Integrated Security=true;" End If Next 'عرض رسالة في حال عدم تواجد القاعدة و اغلاق الاجراء If SqlDbName = "" Then Return MsgBox("القاعدة غير موجودة ضمن السيرفر", , "From SetConnectionString_ForDb") Exit Function End If 'العودة بنص الاتصال مع القاعدة المحددة Return "Data Source=" & PcName & ";" & "Database=" & SqlDbName & ";" _ & "Integrated Security=true;" End Function
الان اجراء يقوم بفتح الاتصال مع القاعدة المحددة وفق رغبتنا مع الشرح
PHP كود :
''' <summary> ''' اجراء يقوم بفتح الاتصال مع قاعدة البيانات المحددة ''' </summary> ''' <returns>يعيد قيمة نصية تمثل حالة الاتصال</returns> ''' <remarks></remarks> Public Shared Function OpenSqlConnection() As String 'فحص حالة الاتصال If SqlConnection.State = ConnectionState.Closed Then 'ربط الاتصال مع القاعدة المحددة _SqlConnectionString = SetConnectionString_ForDb(SqlDbName) 'اسناد نص الاتصال الى كائن الاتصال SqlConnection.ConnectionString = _SqlConnectionString 'فتح الاتصال SqlConnection.Open() End If 'العودة بقيمة توضح حالة الاتصال Return SqlConnection.State.ToString End Function
و اخيرا و ليس اخرا غلق الاتصال مع القاعدة
PHP كود :
''' <summary> ''' اجراء يقوم بغلق الاتصال مع قاعدة البيانات ''' </summary> ''' <returns>يعيد قيمة نصية تمثل حالة الاتصال</returns> ''' <remarks></remarks> Public Shared Function CloseSqlConnection() As String 'فحص حالة الاتصال اذا كان مفتوح يتم اغلاقه If SqlConnection.State = ConnectionState.Open Then SqlConnection.Close() End If 'العودة بقيمة توضح حالة الاتصال Return GetConnectionState() End Function
الان سنقوم بعمل بعض الخصائص التي تفيدنا اثناء عملنا
مذا لو احتجت الى كائن الاتصال و معلومات عنه الا يجب ان يكون لدينا طريقة للوصول اليه , نعم بكل تاكيد
اليك هذه الخاصية للوصول اليه
PHP كود :
''' <summary> ''' خاصية للقراءة فقط تعيد كائن اتصال ''' </summary> ''' <value>القيمة هي كائن اتصال</value> ''' <returns>يعيد كائن اتصال</returns> ''' <remarks></remarks> Shared ReadOnly Property GetSqlConnection() As SqlConnection Get Return SqlConnection End Get End Property
و كذلك لما لا نعيد نص الاتصال يمكن نحتاجه
PHP كود :
''' <summary> ''' خاصية للقراءة فقط ''' تعيد نص الاتصال ''' </summary> ''' <value>القيمة المعادة تمثل نص الاتصال</value> ''' <returns>القيمة المعادة تمثل نص الاتصال</returns> ''' <remarks></remarks> Shared ReadOnly Property GetSQlConnectionString() As String Get Return "Connection String : " & _SqlConnectionString End Get End Property
مع انه يمكننا الحصول على حالة الاتصال بس زيادة الخير خير
PHP كود :
''' <summary> ''' خاصية للقراءة فقط ''' تعيد حالة الاتصال ''' </summary> ''' <value>القيمة المعادة تمثل حالة الاتصال</value> ''' <returns>القيمة المعادة تمثل حالة الاتصال</returns> ''' <remarks></remarks> Shared ReadOnly Property GetConnectionState As String Get Return "Connection State Is : " & SqlConnection.State.ToString End Get End Property
و كمان يمكن نحتاج لاسم السيرفر خلي الكلاس يصير شوربة
PHP كود :
''' <summary> ''' خاصية للقراءة فقط تعيد اسم السيرفر المستخدم ''' </summary> ''' <value>القيمة المعادة تمثل اسم السيرفر</value> ''' <returns>القيمة المعادة تمثل اسم السيرفر</returns> ''' <remarks></remarks> Shared ReadOnly Property GetSrvName As String Get Return "Server Name : " & Srv.Name End Get End Property
و كمان ايضا لدي خطة لاعادة اسماء السيرفرات و اسماء قواعد البيانات و اسماء الجداول في السيرفر لانني ساحتاجها لاحقا ... ساخبرك لاحقا!!!!
السيرفرات
PHP كود :
''' <summary> ''' خاصية للقراءة فقط تعيد نص يمثل اسماء السيرفرات ''' </summary> ''' <value>القيمة المعادة نص يمثل اسماء السيرفرات</value> ''' <returns>القيمة المعادة نص يمثل اسماء السيرفرات</returns> ''' <remarks></remarks> Shared ReadOnly Property ShowServersNames() As String Get Dim SrvN As String = "" For i As Integer = 0 To SrvNameArray.Length - 1 SrvN += SrvNameArray.GetValue(i) & vbCrLf Next
Return SrvN End Get End Property
القواعد
PHP كود :
''' <summary> ''' خاصية للقراءة فقط تعيد اسماء القواعد في السيرفر ''' </summary> ''' <value>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</value> ''' <returns>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</returns> ''' <remarks></remarks> Shared ReadOnly Property GetDbNames() As String Get Dim DbName As String = "" For i As Integer = 0 To srvdbnames.Length - 1 DbName += srvdbnames.GetValue(i) & vbCrLf Next Return DbName End Get End Property
الجداول
PHP كود :
''' <summary> ''' خاصية للقراءة فقط تعيد اسماء الجداول في القاعدة المحددة ''' </summary> ''' <value>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</value> ''' <returns>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</returns> ''' <remarks></remarks> Public Shared ReadOnly Property GetTablesName() As String Get Dim Tablename As String = "" For i As Integer = 0 To TablesSrvDbs.Length - 1 Tablename += TablesSrvDbs.GetValue(i) & vbCrLf Next
Return Tablename End Get End Property
و هذا كود الكلاس كامل منظم
PHP كود :
Imports Microsoft.SqlServer.Management.Common Imports Microsoft.SqlServer.Management.Smo Imports Microsoft.Win32 Imports System.Data.SqlClient Public Class ServSite ''' <summary> ''' متغير من النوع سيرفر ''' نستخدمه للتعامل مع السيرفر ''' </summary> ''' <remarks></remarks> Protected Shared Srv As New Server
''' <summary> ''' متغير من النوع اتصالات السيرفر ''' نستخدمه لتمرير اتصال للسيرفر ''' </summary> ''' <remarks></remarks> Protected Shared srvcon As New ServerConnection
''' <summary> ''' متغير من النوع اتصالات السيكوال نستخدمه للاتصال بقاعدة البيانات ''' </summary> ''' <remarks></remarks> Protected Shared SqlConnection As New SqlConnection
''' <summary> ''' مصفوفة لتخزين اسماء السيرفرات ''' </summary> ''' <remarks></remarks> Protected Shared SrvNameArray() As String
''' <summary> ''' مصفوفة لتخزين اسماء قواعد البيانات ''' نستثني قواعد بيانات النظام ''' </summary> ''' <remarks></remarks> Protected Shared srvdbnames() As String
''' <summary> ''' مصفوفة لتخزين اسماء الجداول في القاعدة المحددة ''' </summary> ''' <remarks></remarks> Protected Shared TablesSrvDbs() As String
''' <summary> ''' متغير نصي نخزن فيه اسم القاعدة المحددة ''' </summary> ''' <remarks></remarks> Protected Shared SqlDbName As String
''' <summary> ''' متغير نصي نخزن فيه نص الاتصال مع قاعدة البيانات ''' </summary> ''' <remarks></remarks> Protected Shared _SqlConnectionString As String ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' <summary> ''' اجراء يقوم بالبحث عن السيرفرات المثبتة على الجهاز ''' و اضافتها الى مصفوفة السيرفرات ويعيد نص اتصال مع السيرفر ''' </summary> ''' <returns>يعود بقيمة نصية تمثل اسم السيرفر الاخير</returns> ''' <remarks>بامكانك استخدام مربع نص او قائمة لاستقبال المخرجات</remarks> Private Shared Function LoadServ() As String Dim Machine As String = Nothing Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Microsoft SQL Server") Dim instances As [String]() = DirectCast(rk.GetValue("InstalledInstances"), [String]()) If instances.Length > 0 Then For Each element As [String] In instances If element = "MSSQLSERVER" Then Machine = (System.Environment.MachineName) ReDim SrvNameArray(instances.Length - 1) instances.CopyTo(SrvNameArray, 0) Else Machine = (System.Environment.MachineName + "\" + element) ReDim SrvNameArray(instances.Length - 1) instances.CopyTo(SrvNameArray, 0)
End If Next
End If srvcon = New ServerConnection(Machine) Srv = New Server(srvcon) Return Machine End Function
''' <summary> ''' اجراء يقوم بتحميل قواعد البيانات في السيرفر المحدد ''' واضافتها الى مصفوفة القواعد ''' </summary> ''' <remarks></remarks> Private Shared Sub loaddbnames() Dim db As New Database Dim j As Integer = 0 For i = 0 To Srv.Databases.Count - 1 If Not Srv.Databases(i).IsSystemObject And Not ((Srv.Databases(i).Name = "")) Then ReDim Preserve srvdbnames(j) db.Name = Srv.Databases(i).Name srvdbnames.SetValue(db.Name, j) j += 1 End If Next End Sub
''' <summary> ''' اجراء يقوم بتحميل جداول القاعدة المحددة ''' و اضافتها الى مصفوفة الجداول ''' </summary> ''' <remarks></remarks> Private Shared Sub LoadTablenames()
If Not (SqlDbName Is Nothing) Or SqlDbName = "" Then Dim Dbs As Database = Srv.Databases(SqlDbName) ReDim TablesSrvDbs(Dbs.Tables.Count) For i = 0 To Dbs.Tables.Count - 1 If Not Dbs.Tables(i).IsSystemObject Then TablesSrvDbs.SetValue(Dbs.Tables(i).Name, i) End If Next End If
End Sub
''' <summary> ''' اجراء يقوم بتاسيس الاتصال مع القاعدة المحددة ''' و يحتاج الى بارميتر نصي يمثل اسم القاعدة ''' </summary> ''' <param name="Dbname">اسم قاعدة البيانات كنص</param> ''' <returns>يعود بقيمة نصية تمثل نص الاتصال</returns> ''' <remarks></remarks> Public Shared Function SetConnectionString_ForDb(ByVal Dbname As String) As String 'فحص طول مصفوفة السيرفرات If SrvNameArray.Length <= 0 Then LoadServ() End If 'فحص طول مصفوفة القواعد If srvdbnames.Length <= 0 Then loaddbnames() End If
'التاكد من وجود سيرفرات على الجهاز من خلال مصفوفة السيرفرات If srvdbnames.Length <= 0 Then Return MsgBox("تاكد من وجود سيرفرات على الجهاز", , "From SetConnectionString_ForDb") Exit Function End If 'التاكد من وجود قواعد على السيرفر من خلال مصفوفة القواعد If srvdbnames.Length <= 0 Then Return MsgBox("تاكد من وجود قواعد على السيرفر", , "From SetConnectionString_ForDb") Exit Function End If 'الحصول على اسم اخر سيرفر Dim PcName As String = LoadServ() 'حلقة لفحص وجود القاعدة المحددةفي مصفوفة القواعد 'ثم اسنادها الى المتغير العام الذي يمثل اسم القاعدة 'ثم تحميل الجداول الموجودة في القاعدة الى مصفوفة الجداول 'و العودة بنص الاتصال مع القاعدة المحددة For i As Integer = 0 To srvdbnames.Length - 1 If (Dbname = srvdbnames(i)) Then SqlDbName = Dbname LoadTablenames() Return "Data Source=" & PcName & ";" & "Database=" & SqlDbName & ";" _ & "Integrated Security=true;" End If Next 'عرض رسالة في حال عدم تواجد القاعدة و اغلاق الاجراء If SqlDbName = "" Then Return MsgBox("القاعدة غير موجودة ضمن السيرفر", , "From SetConnectionString_ForDb") Exit Function End If 'العودة بنص الاتصال مع القاعدة المحددة Return "Data Source=" & PcName & ";" & "Database=" & SqlDbName & ";" _ & "Integrated Security=true;" End Function
''' <summary> ''' اجراء يقوم بفتح الاتصال مع قاعدة البيانات المحددة ''' </summary> ''' <returns>يعيد قيمة نصية تمثل حالة الاتصال</returns> ''' <remarks></remarks> Public Shared Function OpenSqlConnection() As String 'فحص حالة الاتصال If SqlConnection.State = ConnectionState.Closed Then 'ربط الاتصال مع القاعدة المحددة _SqlConnectionString = SetConnectionString_ForDb(SqlDbName) 'اسناد نص الاتصال الى كائن الاتصال SqlConnection.ConnectionString = _SqlConnectionString 'فتح الاتصال SqlConnection.Open() End If 'العودة بقيمة توضح حالة الاتصال Return SqlConnection.State.ToString End Function
''' <summary> ''' اجراء يقوم بغلق الاتصال مع قاعدة البيانات ''' </summary> ''' <returns>يعيد قيمة نصية تمثل حالة الاتصال</returns> ''' <remarks></remarks> Public Shared Function CloseSqlConnection() As String 'فحص حالة الاتصال اذا كان مفتوح يتم اغلاقه If SqlConnection.State = ConnectionState.Open Then SqlConnection.Close() End If 'العودة بقيمة توضح حالة الاتصال Return GetConnectionState() End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' #Region "Propertes"
''' <summary> ''' خاصية للقراءة فقط تعيد كائن اتصال ''' </summary> ''' <value>القيمة هي كائن اتصال</value> ''' <returns>يعيد كائن اتصال</returns> ''' <remarks></remarks> Shared ReadOnly Property GetSqlConnection() As SqlConnection Get Return SqlConnection End Get End Property
''' <summary> ''' خاصية للقراءة فقط ''' تعيد نص الاتصال ''' </summary> ''' <value>القيمة المعادة تمثل نص الاتصال</value> ''' <returns>القيمة المعادة تمثل نص الاتصال</returns> ''' <remarks></remarks> Shared ReadOnly Property GetSQlConnectionString() As String Get Return "Connection String : " & _SqlConnectionString End Get End Property
''' <summary> ''' خاصية للقراءة فقط ''' تعيد حالة الاتصال ''' </summary> ''' <value>القيمة المعادة تمثل حالة الاتصال</value> ''' <returns>القيمة المعادة تمثل حالة الاتصال</returns> ''' <remarks></remarks> Shared ReadOnly Property GetConnectionState As String Get Return "Connection State Is : " & SqlConnection.State.ToString End Get End Property
''' <summary> ''' خاصية للقراءة فقط تعيد اسم السيرفر المستخدم ''' </summary> ''' <value>القيمة المعادة تمثل اسم السيرفر</value> ''' <returns>القيمة المعادة تمثل اسم السيرفر</returns> ''' <remarks></remarks> Shared ReadOnly Property GetSrvName As String Get Return "Server Name : " & Srv.Name End Get End Property
''' <summary> ''' خاصية للقراءة فقط تعيد اسماء القواعد في السيرفر ''' </summary> ''' <value>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</value> ''' <returns>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</returns> ''' <remarks></remarks> Shared ReadOnly Property GetDbNames() As String Get Dim DbName As String = "" For i As Integer = 0 To srvdbnames.Length - 1 DbName += srvdbnames.GetValue(i) & vbCrLf Next Return DbName End Get End Property
''' <summary> ''' خاصية للقراءة فقط تعيد اسماء الجداول في القاعدة المحددة ''' </summary> ''' <value>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</value> ''' <returns>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</returns> ''' <remarks></remarks> Public Shared ReadOnly Property GetTablesName() As String Get Dim Tablename As String = "" For i As Integer = 0 To TablesSrvDbs.Length - 1 Tablename += TablesSrvDbs.GetValue(i) & vbCrLf Next
Return Tablename End Get End Property
''' <summary> ''' خاصية للقراءة فقط تعيد نص يمثل اسماء السيرفرات ''' </summary> ''' <value>القيمة المعادة نص يمثل اسماء السيرفرات</value> ''' <returns>القيمة المعادة نص يمثل اسماء السيرفرات</returns> ''' <remarks></remarks> Shared ReadOnly Property ShowServersNames() As String Get Dim SrvN As String = "" For i As Integer = 0 To SrvNameArray.Length - 1 SrvN += SrvNameArray.GetValue(i) & vbCrLf Next
Return SrvN End Get End Property
#End Region
End Class
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16
ناتي الان للمفيد و الشغل الجامد
الكلاس الثاني في مشروعنا هو كلاس التعامل مع قاعدة البيانات (الحذف و التعديل و الاضافة)
بس؟؟؟؟
بس و الباقي عليك انت؟؟
وجهة نظري تقول اذا كنت قد حصلت على اتصال مع السرفر و حددت القاعدة و الجدول الذي اريده و لدي ايضا كل الحقول التي اريدها
لماذا لا يكون لدي جمل استعلام ديناميكية تقوم لوحدها بتركيب نفسها اعتمادا على مدخلات بسيطة مني
فقط انا امرر اسماء الحقول و هي تقوم بعمل جمل (SELECT,INSERT,UPDATE,DELETE) لوحدها دون ان اقوم انا بكتابتها
تخيل معي لو كان لديك جدول فيه 50 حقل هل ساقوم انا بكتابتها و اعيد تكرار الكتابة و ووووو.....؟ عمل ممل و سقيم
اذا ما الفائدة من الكلاس اللي عملناه..؟ سؤال وجيه يحتاج لاجابة
لندخل في المفيد
انشأ كلاس جديد و اضفه الى المشروع و سميه DbConect
داخل الكلاس استورد المراجع التالية و قم بتوريث الكلاس السابق الى الكلاس الجديد للاستفادة من الكائنات التي عملناها سابقا
PHP كود :
Imports Microsoft.SqlServer.Management.Common Imports Microsoft.SqlServer.Management.Smo Imports Microsoft.SqlServer.Management.Sdk.Sfc Imports System.Data.SqlClient Imports System.Data.Common
Public Class DbConect Inherits ServSite
ان فكرةعمل كلاس خاص بكل جدول و بكل الحقول الخاصة فيه هي فكرة لا تلبي حاجتنا لان الجداول متغيرة و كذلك الحقول و انا اريد كلاس ديناميكي
اذا ساحاول الاستفادة من الكلاس السابق لاقصى درجة ممكنة
الفكرة التي لدي هي الاستفادة من الجداول و الحقول التي خزناها سابقا و جلبها الى مصفوفات خاصة و من ثم التعامل معها عبر المصفوفات
الان مجموعة من المتغيرات في بداية الكلاس مع الشرح داخلها
PHP كود :
Private WithEvents _adapter As SqlClient.SqlDataAdapter ''' <summary> ''' مصفوفة من بعدين ''' البعد الاول يخزن اسم الحقل ''' البعد الثاني يخزن نوع البيانات ''' </summary> ''' <remarks></remarks> Dim Column(2, 0)
''' <summary> ''' مصفوفة ببعد واحد لتخزين اسماء حقول الجدول ''' </summary> ''' <remarks></remarks> Dim AllColumn() As String
''' <summary> '''متغير جدول بيانات نخزن فيه حقول جدول قاعدة ''' السيكوال الذي مررناه للتعامل معه ''' </summary> ''' <remarks></remarks> Protected Dt As DataTable
''' <summary> ''' مصفوفة من النوع حقل بيانات ''' لتخزين المفتاح الرئيسي في الكائن جدول البيانات ''' </summary> ''' <remarks></remarks> Dim kyes(0) As DataColumn
Dim allParameters() As SqlParameter ''' <summary> ''' مصفوفة رباعية الابعاد ''' البعد الاول نخزن فيه اسم الحقل ''' البعد الثاني لتخزين نوع بيانات الحقل ''' البعد الثالث لتخزين اسم بارميتر مرافق للحقل ''' البعد الرابع نخزن فين نص يشير الى حقل المفتاح الرئيسي ''' </summary> ''' <remarks></remarks> Dim InsUpSel(4, 0) 'As String
''' <summary> ''' متغير نصي نستخدمه للاحتفظ باسم الجدول الذي نريد التعامل معه ''' </summary> ''' <remarks></remarks> Protected _TableName As String
شرح بسيط عن المصفوفة رباعية الابعاد (جدول باربع اعمده ليسهل الفهم)
البعد الثالث في هذه المصفوفة هو لتخزين بارميتر خاص مرافق للحقل
اذ قررت ان اتعامل مع الكائن SQL COMMAND للتخاطب مع قاعدة البيانات و بالتالي انا مضطر لارسال بارميتر لكل حقل اريد تحديثه هذا يقودنا الى مجموعه من البارمترات كذلك متغيرة على حسب عدد الحقول بالمختصر المفيد انا اجهل عددها و اسمائها لذا ستكون البارمترات على حسب عدد الحقول التي ناتي بها مع استثناء حقل المفتاح الرئيسي اثناء عملية الاضافة
عملية انشاء البارمترات ستتم وفق اسم الحقل في مصفوفة الحقول على فرض انا لدي حقل اسمه Name البارميتر المناسب سيكون @Name
و هكذا ....
في البداية بعد تاسيس الاتصال مع القاعدة ساكون بحاجه الى جدول للتعامل معه , لذا سأنشئ خاصية للتعامل مع الجدول باتجاهين
استطيع من خلالها اسناد اسم للجدول و كذلك معرفة اسم الجدول الحالي
PHP كود :
''' <summary> ''' خاصية اسناد اسم للجدول للتعامل معه ''' او الحصول على اسم الجدول ''' </summary> ''' <value>حدد اسم الجدول كنص</value> ''' <returns>نص يمثل اسم الجدول</returns> ''' <remarks> ''' يتوجب ان يكون هتاك اتصال مع قاعدة البيانت ''' كما يتوجب تحديد اسم الجدول بشكل صحيح ''' </remarks> Property TableName() As String
Set(ByVal value As String) If _SqlConnectionString Is Nothing Or _SqlConnectionString = "" Then MsgBox("تاكد من تاسيس نص الاتصال", , "From TableName") Exit Property End If
'------------------------------------------ For i As Integer = 0 To TablesSrvDbs.Length - 1 If (value = TablesSrvDbs(i)) Then _TableName = value LoadTxtFiled() ElseIf i >= TablesSrvDbs.Length And (value <> TablesSrvDbs(i)) Then _TableName = "" End If Next '--------------------------------------- If _TableName = "" Then MsgBox("حدد اسم الجدول بشكل صحيح", , "From TableName") Exit Property End If End Set
Get Return _TableName End Get
End Property
طبعا في الكود السابق ساستفيد من مصفوفة الجداول التي انشأناها سابقا للتاكد من وجود اسم الجدول ضمن المصفوفة بعد ان يكون المستخدم قد ادخله و من ثم العودة باسم الجدول
بعد الحصول على الجدول يتبقى الحصول على الحقول بداخله بخاصية للقراءة فقط اذ ان اسماء الحقول ستاتي جاهزة كما هي
PHP كود :
ReadOnly Property GetAllFields() As String Get If _TableName = "" Then
Return MsgBox("حدد اسم الجدول اولا", , "From GetAllFields") Exit Property End If Dim op As String = "" For i = 0 To AllColumn.Length - 1 op += AllColumn(i) & vbCrLf Next
Return op End Get End Property
بعد ذلك انا امام اجراء كبير لكنه سهل في مجمله و الغاية منه هو ملئ المصفوفات التي عرفناها فوق بالمعلومات عن كل الحقول
انا شرحت الكود ضمن التعليقات داخله
PHP كود :
''' <summary> ''' اجراء تخزين اسماء الاعمدة و نوعها في مصفوفة '''هذا الاجراء يقوم بالمرور على كل اعمدة الجدول المحدد '''AllCoulmn يقوم بتخزين اسماء الاعمدة في مصفوفة نصية '''Coulmn(,) يقوم بتخزين اسماء الاعمدة و نوعها في مصفوفة نصية ثنائية البعد ''' Dt As DataTable يقوم بتخزين الاعمدة في جدول من النوع ''' DT كما و يقوم باضافة المفتاح الرئيسي الى الجدول ''' InsUpSel(4,0) و يخزن ايضا اسماء الاعمدة و بارميتر لكل عمود و المفتاح الرئيسي ونوع البيانات في ''' </summary> Protected Sub LoadTxtFiled() '================================ If _TableName = "" Then Return End If '================================= Dim Tabl_name As String = _TableName Dim tb As Table = Srv.Databases(SqlDbName).Tables(Tabl_name) Dim cs As Integer = 0 ' Dt = New DataTable() Dt.Columns.Clear() Array.Clear(kyes, 0, kyes.Length) '================================ For Each dc As Column In tb.Columns ' Dim DTc As New DataColumn DTc.ColumnName = dc.Name DTc.AllowDBNull = dc.Nullable ' ReDim Preserve InsUpSel(4, cs) ReDim Preserve AllColumn(cs) AllColumn.SetValue(dc.Name, cs) InsUpSel.SetValue(dc.Name, 0, cs) ' ReDim Preserve Column(2, cs) Column.SetValue(dc.Name, 0, cs)
Select Case (dc.DataType.SqlDataType) Case Is = SqlDataType.NVarChar Column.SetValue(SqlDbType.NVarChar, 1, cs) InsUpSel.SetValue(SqlDbType.NVarChar, 1, cs) DTc.DataType = System.Type.GetType("System.String") Case Is = SqlDataType.VarChar Column.SetValue(SqlDbType.VarChar, 1, cs) InsUpSel.SetValue(SqlDbType.VarChar, 1, cs) DTc.DataType = System.Type.GetType("System.String") Case Is = SqlDataType.NChar Column.SetValue(SqlDbType.NChar, 1, cs) InsUpSel.SetValue(SqlDbType.NChar, 1, cs) DTc.DataType = System.Type.GetType("System.String") Case Is = SqlDataType.Int Column.SetValue(SqlDbType.Int, 1, cs) InsUpSel.SetValue(SqlDbType.Int, 1, cs) DTc.DataType = System.Type.GetType("System.Int32") Case Is = SqlDataType.Date Column.SetValue(SqlDbType.Date, 1, cs) InsUpSel.SetValue(SqlDbType.Date, 1, cs) DTc.DataType = System.Type.GetType("System.DateTime") Case Is = SqlDataType.DateTime Column.SetValue(SqlDbType.DateTime, 1, cs) InsUpSel.SetValue(SqlDbType.DateTime, 1, cs) DTc.DataType = System.Type.GetType("System.DateTime") Case Is = SqlDataType.Float Column.SetValue(SqlDbType.Float, 1, cs) InsUpSel.SetValue(SqlDbType.Float, 1, cs) DTc.DataType = System.Type.GetType("System.Double") Case Is = SqlDataType.Image Column.SetValue(SqlDbType.Image, 1, cs) InsUpSel.SetValue(SqlDbType.Image, 1, cs) DTc.DataType = System.Type.GetType("System.Byte") Case Is = SqlDataType.Decimal Column.SetValue(SqlDbType.Decimal, 1, cs) InsUpSel.SetValue(SqlDbType.Decimal, 1, cs) DTc.DataType = System.Type.GetType("System.Decimal") End Select InsUpSel.SetValue("@" & dc.Name, 2, cs)
If dc.InPrimaryKey Then Column.SetValue("prim", 2, cs) InsUpSel.SetValue("prim", 3, cs) ' DTc.AutoIncrement = True DTc.AutoIncrementSeed = -1 DTc.AutoIncrementStep = -1 DTc.AllowDBNull = False DTc.ReadOnly = True DTc.Unique = True ReDim kyes(cs) kyes(cs) = DTc Dt.Columns.Add(DTc) End If cs += 1
Next
If kyes.Length > 0 Then Dt.PrimaryKey = kyes End If End Sub
بعد ان تم ملئ المصفوفات بالبيانات اللازمة جاء دور العمل مع جمل الاستعلام الديناميكية و الاستفادة من كل المعلومات السابقة لاستخلاص جملة تحديد مناسبة على ذوق المبرمج
انا فضلت العمل بطريقتين هنا
اذا ود المبرمج ان يحدد كل الحقول فعليه ان يختار المعامل *
و اذا ود اختيار مجموع من الحقول فقط فعليه ادخال اسماء الحقول فقط ضمن مصفوفة بسيط (مصفوفة من ثاني )
نسيت ان اشير الى جزئية هامة في الكود السابق و هي نوع بيانات الحقول القادمة من SQL SERVER يتم تحويلها الى انواع تتوافق مع اطار العمل
انا قمت بتحويل بعض الانواع فقط لذا يمكنك ان تقوم بتوسيع عملية التحويل حسب رغبتك
يتبع.............
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16
الان مع جملة التحديد ,سنبدأ الاستفادة من كل المعلومات التي قمنا بتخزينها سابقا
سنقوم بعمل جملة تحديد بسيطة نعبئ فيها الحقول من مصفوفة الحقول التي انشأناها سابقا وفق حلقة تكرارية
و سنفحص اذا ما كان الحقل هو مفتاح رئيسي في قائمة الحقول لنضيفه الى جملة التحديد ايضا
و كذلك سنضيف قائمة البارمترات المرافقة للحقول من المصفوفة الموافقة الى كائن SQL COMMAND
توقف اخي ؟؟؟ لماذا ساضيف بارمترات مع جملة التحديد
ربما تحتاجها مستقبلا اذا ما نويت التوسع في الكلاس كان تجري عمليات بحث و فلترة و غيرها من الامور المعتمدة على البارمترات
الكود التالي يوضح العملية مع الشرح
PHP كود :
''' <summary> ''' اجراء يقوم بانشاء جملة تحديد لبيانات الجدول المحدد ''' يمكنك تحديد كل حقول الجدول بواسطة ''' علامة * في مصفوفة الحقول ''' او تحديد الحقول التي تريدها ''' </summary> ''' <param name="Command">كائن الكوماند</param> ''' <param name="Columns">مصفوفة نصية تحتوي على الحقول</param> ''' <returns>يعود بكائن كوماند يحمل جملة التحديد</returns> ''' <remarks></remarks> Private Function Create_Select_For_Command(ByVal Command As SqlCommand, ByVal ParamArray Columns() As String) As SqlCommand
If _TableName = "" Or _TableName Is Nothing Then MsgBox("حدد اسم الجدول اولا", , "From Create_Select_For_Command") Return Nothing Exit Function End If '**********************************************
Dim SelectColumns As String = "Select " '& "(" Dim filed As String = "" Dim sa As Integer = 0 Dim qf As Integer = 0 Dim qfiled As String = "" '----------------------------------- Command.Connection = GetSqlConnection ' If Columns(0) = "*" Then
For ic = 0 To InsUpSel.GetLength(1) - 1 If qf = InsUpSel.GetLength(1) - 1 Then qfiled += InsUpSel(0, ic) Else qfiled += InsUpSel(0, ic) & "," End If qf += 1 Next SelectColumns += qfiled & " From " & _TableName qfiled = "" qf = 0
ElseIf Columns(0) <> "*" And Columns.Length >= 0 Then Columns = Columns If checkfileds(Columns) = True Then Return Nothing Exit Function End If
For Each Str As String In Columns For ic = 0 To InsUpSel.GetLength(1) - 1 If Str = InsUpSel(0, ic) Then If qf = Columns.Length - 1 Then qfiled += InsUpSel(0, ic) Else qfiled += InsUpSel(0, ic) & "," End If End If Next qf += 1 Next SelectColumns += qfiled & " From " & _TableName End If ' Command.CommandText = SelectColumns Return Command End Function
اذا دققت في الكود السابق ستجد ان لديك الاجراء checkfileds
هذا الاجراء مهمته تفحص تواجد الحقول المدخلة من قبل المستخدم و مطابقتها مع مصفوفة الحقول لدينا
لكي لا يدخل المستخدم اسم حقل غير موجود لدينا
PHP كود :
''' <summary> ''' ''اجراء يقوم بفحص الحقول الممرة وفق مصفوفة الحقول ''' ويختبر تواجدها في الجدول ''' </summary> ''' <param name="ColCheck">البارميتر هو مصفوفة من الحقول </param> Private Function checkfileds(ByVal ParamArray ColCheck() As String) As Boolean Dim flds(0) As String Dim check As Boolean For m = 0 To InsUpSel.GetLength(1) - 1 ReDim Preserve flds(m) flds.SetValue(InsUpSel(0, m), m)
Next
For Each t As String In ColCheck If Not (flds.Contains(t)) Then MsgBox("لا يوجد حقل بالاسم(" & t & ") في الجدول(" & _TableName & ")", , "الرسالة قادمة من الاجراء checkfileds") Return check = True Exit Function End If Next Return check End Function
الان ننتقل الى UPDATE
عملية تحديث البيانات في القاعدة تعتمد على شيئ اساسي الا و هو عمود المفتاح الرئيسي اذا ان جملة التحديث تبقى عمياء بدون هذا الحقل ولا تعرف اي حقل تريد ان تحدث لذا وجب ان يكون البارميتر الخاص بهذا الحقل اساسي يعني يحمل القيمة الحقيقة
عملية تحديد الحقول كما سابقها في جملة SELECT
PHP كود :
''' <summary> ''' 'يقوم هذا الاجراء بانشاء جملة تحديث للجدول المحدد ''' و يقوم باسنادها الى الكوماند المطلوب ''' يحتاج الى بارميترين الاول هو كائن الكوماند ''' و الثاني هو مصفوفة الحقول بامكانك تمرير علامة * في الاشارة الى كافة الحقول ''' او تمرير الحقول حسب الرغبة كما يلي ''' </summary> ''' <param name="Command"> ''' كائن الكوماند ''' </param> ''' <param name="Columns">مصفوفة نصية تحتوي على اسماء الحقول</param> ''' <returns>يعود بكائن كوماند يحمل جملة التحديث</returns> ''' <remarks> ''' </remarks> Private Function Create_update_For_Command(ByVal Command As SqlCommand, ByVal ParamArray Columns() As String) As SqlCommand If _TableName = "" Or _TableName Is Nothing Then MsgBox("حدد اسم الجدول اولا", , "From Create_update_For_Command ") Return Nothing Exit Function End If '---------------------------------------------------------------- Dim Updatest As String = ""
Dim qfiled As String = "" Dim CurrentKey As String = "" Dim OrginalKey As String = "" Dim qf As Integer = 0 Dim qparm As New SqlParameter '*********************************************** Command.Connection = GetSqlConnection Command.Parameters.Clear() '--------------------------------------------------------------------------------------- '''''''''
If Columns(0) = "*" Then For ic = 0 To InsUpSel.GetLength(1) - 1 qparm = New SqlParameter If Not (InsUpSel(3, ic) = "prim") Then If qf = InsUpSel.GetLength(1) - 1 Then qfiled += InsUpSel(0, ic) & "=" & InsUpSel(2, ic) qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm) Else qfiled += InsUpSel(0, ic) & "=" & InsUpSel(2, ic) & "," qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm)
End If Else
CurrentKey = InsUpSel(0, ic) OrginalKey = InsUpSel(2, ic) qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm) ''''''' qparm = New SqlParameter qparm.ParameterName = "@Orginal_" & InsUpSel(0, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) qparm.SourceVersion = DataRowVersion.Original Command.Parameters.Add(qparm) End If
qf += 1 Next Updatest = "Update " & _TableName & " Set " & qfiled & " Where " & CurrentKey & " = " & OrginalKey ' qfiled = "" CurrentKey = "" OrginalKey = "" qf = 0 '
ElseIf Columns(0) <> "*" And Columns.Length >= 1 Then Columns = Columns ' If checkfileds(Columns) = True Then Return Nothing Exit Function End If ' For Each Str As String In Columns
For ic = 0 To InsUpSel.GetLength(1) - 1 If Not (InsUpSel(3, ic) = "prim") Then
If Str = InsUpSel(0, ic) Then qparm = New SqlParameter If qf = Columns.Length - 1 Then qfiled += InsUpSel(0, ic) & "=" & InsUpSel(2, ic) qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm) Else qfiled += InsUpSel(0, ic) & "=" & InsUpSel(2, ic) & "," qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm)
End If
End If
ElseIf InsUpSel(3, ic) = "prim" And Not (Command.Parameters.Contains(OrginalKey)) Then CurrentKey = "" OrginalKey = "" CurrentKey = InsUpSel(0, ic) OrginalKey = InsUpSel(2, ic) qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) Command.Parameters.Add(qparm) '''''''''' If Not (Command.Parameters.Contains("@Orginal_" & CurrentKey)) Then
qparm = New SqlParameter qparm.ParameterName = "@Orginal_" & CurrentKey qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) qparm.SourceVersion = DataRowVersion.Original qparm.Direction = ParameterDirection.Output Command.Parameters.Add(qparm) End If End If Next qf += 1 Next
Updatest = "Update " & _TableName & " Set " & qfiled & " Where " & CurrentKey & " = " & OrginalKey ' MsgBox(Updatest)
End If Command.CommandText = Updatest
Return Command End Function
الادخال INSERT
لا شيئ جديد حددنا الحقول كما سابقه و قمنا فقط باستثناء البارميتر الخاص بالمفتاح الرئيسي اذا كان الحقل الذي تتعامل معه من النوع ترقيم تلقائي او قم باضافته اذا كنت تستخدم حقل خاص بك لكن تذكر ان تفحص قيمة الحقل قبل الارسال لكي لا تنشئ لديك قيم مكررة
PHP كود :
''' <summary> ''' اجراء يقوم بانشاء جملة ادخال للكوماند المحدد ''' يتم استخدام اسم الجدول المحدد ''' يتم من خلاله انشاء بارميترات للكوماند المحدد ''' توافق اسماء الحقول في الجدول ''' </summary> ''' <param name="Command">مرر اسم الكوماند فقط</param> ''' <param name="Columns">مرر مصفوفة نصية تحتوي على اسماء الحقول بامكانك استخدام علامة * للاشارة الى كل الحقول</param> ''' <returns>يعيد كائن كوماند يحمل جملة الادخال</returns> ''' <remarks> ''' ان اي خطأ في اسماء الحقول لن يعمل الاجراء بشكل صحيح ''' <example> ''' <code> ''' Dim Cols() As String = {"name","phone"} ''' </code> ''' </example> ''' </remarks> Private Function Create_Insert_For_Command8(ByVal Command As SqlCommand, ByVal ParamArray Columns() As String) As SqlCommand If _TableName = "" Or _TableName Is Nothing Then MsgBox("حدد اسم الجدول اولا", , "from Create_Insert_For_Command ") Return Nothing Exit Function End If '----------------------------------------------------------------- Command = Command Command.Connection = GetSqlConnection Command.Parameters.Clear() '============================================================= Dim insertall As String = "" Dim select1 As String = "Select " Dim qfiled As String = "" Dim qvalue As String = "" Dim qf As Integer = 0 Dim qparm As New SqlParameter If Columns(0) = "*" Then
For ic = 0 To InsUpSel.GetLength(1) - 1 qparm = New SqlParameter If Not (InsUpSel(3, ic) = "prim") Then If qf = InsUpSel.GetLength(1) - 1 Then qfiled += InsUpSel(0, ic) qvalue += InsUpSel(2, ic) qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm) Else qfiled += InsUpSel(0, ic) & "," qvalue += InsUpSel(2, ic) & "," qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm)
End If
End If
qf += 1 Next
If InsUpSel(3, 0) = "prim" Then Dim keyorginal As String keyorginal = InsUpSel(0, 0) select1 += keyorginal & "," & qfiled & " from " & _TableName & " Where " & keyorginal & " = " & " SCOPE_IDENTITY()" Else select1 += qfiled & " from " & _TableName End If
insertall = "INSERT INTO " & _TableName & vbCrLf & " (" & qfiled & ")" & vbCrLf & "Values " & vbCrLf & "(" & qvalue & ")" & vbCrLf & select1
Command.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord qfiled = "" qf = 0
ElseIf Columns(0) <> "*" And Columns.Length >= 1 Then Columns = Columns If checkfileds(Columns) = True Then Return Nothing Exit Function End If
For Each Str As String In Columns For ic = 0 To InsUpSel.GetLength(1) - 1 If Not (InsUpSel(3, ic) = "prim") Then If Str = InsUpSel(0, ic) Then qparm = New SqlParameter If qf = Columns.Length - 1 Then qfiled += InsUpSel(0, ic) qvalue += InsUpSel(2, ic) qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm) ' Exit For Else qfiled += InsUpSel(0, ic) & "," qvalue += InsUpSel(2, ic) & "," qparm.ParameterName = InsUpSel(2, ic) qparm.SqlDbType = InsUpSel(1, ic) qparm.SourceColumn = InsUpSel(0, ic) Command.Parameters.Add(qparm)
End If Else
End If End If
Next qf += 1 Next insertall = "INSERT INTO " & _TableName & vbCrLf & " (" & qfiled & ")" & vbCrLf & "Values " & vbCrLf & "(" & qvalue & ")"
End If
Command.CommandText = insertall Return Command
End Function
عملية الحذف DELETE
الحذف يجري بطريقة معتادة وفق قيمة المفتاح الرئيسي و هو معروف لديكم جميعا
كما انني اردت ان اعمل طريقة اخرى لحذف كل محتويات الجدول
الحذف وفق معيار محدد
PHP كود :
''' <summary> ''' اجراء يقوم بانشاء جملة استعلام لعملية حذف صف محدد ''' وفق قيمة المفتاح الرئيسي ''' </summary> ''' <param name="Command">كائن الكوماند</param> ''' <returns>يعود بكائن الكوماند المرسل</returns> ''' <remarks></remarks> Private Function Create_Delete_For_Command(ByVal Command As SqlCommand) As SqlCommand If _TableName = "" Or _TableName Is Nothing Then MsgBox("حدد اسم الجدول اولا", , "From Create_Delete_For_Command ") Return Nothing Exit Function End If '----------------------------------------------------------------------- Command = Command Command.Connection = GetSqlConnection Command.Parameters.Clear()
Dim Deletest As String = "Delete From " & _TableName & " Where " Dim parm As New SqlParameter '
Dim OrginalKye As String = "" For ic = 0 To InsUpSel.GetLength(1) - 1 If InsUpSel(3, ic) = "prim" Then OrginalKye = InsUpSel(0, ic) parm.ParameterName = InsUpSel(2, ic) parm.SqlDbType = InsUpSel(1, ic) parm.SourceColumn = InsUpSel(0, ic) parm.SourceVersion = DataRowVersion.Original Command.Parameters.Add(parm)
End If Next Deletest += "(" & OrginalKye & "=" & "@" & OrginalKye & ")"
'
Command.CommandText = Deletest Return Command End Function
حذف كامل الصفوف في الجدول المحدد
PHP كود :
''' <summary> ''' اجراء يقوم بانشاء جملة استعلام لعملية حذف ''' كل الصفوف في الجدول المحدد ''' </summary> ''' <param name="Command">كائن كوماند</param> ''' <returns>يعود بكائن الكوماند المرسل</returns> ''' <remarks></remarks> Private Function Create_DeleteAll_For_Command(ByVal Command As SqlCommand) As SqlCommand If _TableName = "" Or _TableName Is Nothing Then MsgBox("From Create_DeleteAll_For_Command " & "حدد اسم الجدول اولا") Return Nothing Exit Function End If
'----------------------------------------------------------------------- Command = Command Command.Connection = GetSqlConnection '-------------------------------------------------------------------------- Dim Deletest As String = "Delete From " & _TableName
Command.CommandText = Deletest Return Command End Function
ماذا بعد ذلك
احببت ان اضمن كل عملنا السابق و اضافة كل كائنات SQL COMMANDS الى كائن SQL DATA ADAPTER
ليتكفل هو بالعملية كاملة يمكنك تخطيها اذا احببت
PHP كود :
''' <summary> ''' اجراء يقوم بتمهيد كائن الادبتر وفق الجدول المحدد ''' و يقوم بتجهيز كائنات الكوماند المناسبة مع البارمترات اللازمة ''' </summary> ''' <param name="Columns"> * مصفوفة الحقول يمكنك استخدام علامة </param> ''' <returns>يعيد كائن ادبتر </returns> ''' <remarks></remarks> Public Function Creat_Adapter(ByVal ParamArray Columns() As String) As SqlDataAdapter
Dim table1 As String = TableName LoadTxtFiled() '---------------- Me._adapter = New SqlClient.SqlDataAdapter() Dim tableMapping As DataTableMapping = New DataTableMapping() tableMapping.SourceTable = table1 ' "Table" tableMapping.DataSetTable = table1 '"class" '------------------------------------------------------------------ If Dt.Columns.Count > 0 Then For Each dc As DataColumn In Dt.Columns tableMapping.ColumnMappings.Add(dc.ColumnName, dc.ColumnName) Next Me._adapter.TableMappings.Add(tableMapping) End If '--------------------------------------------------------------------------- Dim SelCommand As New SqlClient.SqlCommand Dim UpCommand As New SqlClient.SqlCommand Dim InsCommand As New SqlClient.SqlCommand Dim DelCommand As New SqlClient.SqlCommand '-------------------- SelCommand = Me.Create_Select_For_Command(SelCommand, Columns) '------------------- UpCommand = Me.Create_update_For_Command(UpCommand, Columns) '------------------- InsCommand = Me.Create_Insert_For_Command8(InsCommand, Columns) '----------------- DelCommand = Me.Create_Delete_For_Command(DelCommand) '---------------------- Me._adapter.SelectCommand = SelCommand Me._adapter.InsertCommand = InsCommand Me._adapter.UpdateCommand = UpCommand Me._adapter.DeleteCommand = DelCommand Me._adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey Return Me._adapter End Function
(25-06-16, 04:29 AM)khodor1985 كتب : بتصور فينا نكتب الكلاس بطريقة أسهل من هيك، هيدا رأيي طبعا.
مشكور على جهودك
مشكور اخي خضر على المشاركة اكيد فيك تكتبه بطرق سهلة اكثر و حسب مزاجك
الموضوع برمته كان على عجالة و الكلاس سيتم تجريبه اكثر للتاكد من عمله
و يمكن الاستفادة من الالية لتطويرها بما يتناسب مع تصورك للهدف
بعد ذلك لم يتبقى لدينا الى عملية تخريج الكلاس BUILD لنحصل على ملف Dll نستخدمه في مشروعنا
ساقوم بوضع تجريب بسيط للتعامل مع الكلاس لاحقا
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 26-06-16
كلام جميل اخي خضر و هذه الهندسة هي اللبنة الاساسية في بناء برامج كبيرة
نحن نستخدم هذه التقنية لبناء البرامج التجارية في اغلب الاحيان
انا عن نفسي لا احب استخدام اي جزء يختص بالتعامل مع البيانات في واجهة البرنامج , كله يكون في قاعدة البيانات
اما من ناحية البرنامج فلا احتاج الا بناء الكلاسات الخاصة للتخاطب مع القاعدة و من ثم واجهة المستخدم التي تتخاطب مع الكلاسات السابقة
هكذا تكون قد فصلت كل شيئ لوحده
يوجد من الكلام الكثير الكثير عن هذه التقنية ربما في قادم الايام ان شاء الله ستكون لي وقفة مفصلة و يا ريت بالتعاون مع شخصكم و باقي الاعضاء للخروج بمرجع جيد عنها
تحياتي لك
بسم الله الرحمن الرحيم
استكمالا لما سبق ساضع مثال تجريب على الكلاس الذي انشأناه سابقا للتجريب
اولا سانشئ قاعدة بيانات بسيطة على السيرفر مؤلفة من 3 جداول
جدول الزبائن
جدول الطلبيات او الفواتير
جدول تفاصيل الفاتورة او المواد
و ساضع السكربت الخاص بها اسفل الموضوع
اردت استخدام الكلاس السابق مباشرة في عملية التحديث على القاعدة , على كل الجداول السابقة
و ساعمل نموذج في واجهة اللغة كما يلي
سنستورد الكلاس السابق الذي اصبح مكتبة الى مراجعنا و نتعامل معه كما ساعرف بعض الكائنات للتعامل الجداول السابقة كما يلي
PHP كود :
Imports System.Data.SqlClient Imports SQLDBConnect
Public Class Clients Dim da1, da2, da3 As SqlClient.SqlDataAdapter Dim ds As New DataSet Dim d1, d2, d3 As New DbConect
انا عدلت على الكلاس السابق في جزئية جلب السيرفرات فقط حيث لم تعمل معي في الوندوز 10 مع انها مازالت تعمل في وندوز 7
على اي حال انا ساضع الكلاس مرفق مع المثال
الكود التالي في حدث تحميل النموذج و هو مشروح بالكامل
PHP كود :
Private Sub Clients_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'تعين الاتصال الى القاعدة DbConect.SetConnectionString_ForDb("ClientDb") 'فتح الاتصال DbConect.OpenSqlConnection() 'تحديد اسماء الجداول التي نريد التعامل معها d1.TableName = "ClientsTb" d2.TableName = "OrdersTb" d3.TableName = "GoodsTb" 'هنا انا اخترن جميع الحقول Dim fild() As String = {"*"} 'تفريغ الداتاسيت ds.Clear() '---------------------------------- 'Adapter انشاء كائنات 'و ربطها مع الجداول السابقة da1 = New SqlClient.SqlDataAdapter da1 = d1.Creat_Adapter(fild) '------------ da2 = New SqlClient.SqlDataAdapter da2 = d2.Creat_Adapter(fild) '------------------------ da3 = New SqlClient.SqlDataAdapter da3 = d3.Creat_Adapter(fild) 'ملئ الداتاسيت ببيانات الجداول da1.Fill(ds, d1.TableName) da2.Fill(ds, d2.TableName) da3.Fill(ds, d3.TableName) ds.AcceptChanges()
'انشاء علاقات بين الجداول '----------------------------.زبائن و طلبيات------------------------------------- Dim col1 As DataColumn = ds.Tables(d1.TableName).Columns("Cl_Id") 'جدول الزبائن Dim col2 As DataColumn = ds.Tables(d2.TableName).Columns("Cl_Id") 'جدول الطلبيات Dim re As New DataRelation("Clt_Ord", col1, col2) ds.Relations.Add(re) ''----------------------------طلبيات و مواد--------------------------------------- Dim col4 As DataColumn = ds.Tables(d2.TableName).Columns("Ord_Id") 'جدول الطلبيات Dim col5 As DataColumn = ds.Tables(d3.TableName).Columns("Ord_Id") 'جدول المواد Dim re3 As New DataRelation("Ord_Gods", col4, col5) ds.Relations.Add(re3) 'BindingSource ربط كائنات 'بمصدر بيانات bn1.DataSource = ds.Tables(d1.TableName) bn2.DataSource = bn1 bn2.DataMember = "Clt_Ord" bn3.DataSource = bn2 bn3.DataMember = "Ord_Gods" 'DataGrids و كذلك ربط Dg1.DataSource = bn1 dg2.DataSource = bn2 dg3.DataSource = bn3 'اغلاق الاتصال DbConect.CloseSqlConnection() 'عرض اسم السيرفر و حالة الاتصال و جملة الاتصال اسفل النموذج ST1.Items(0).Text = DbConect.GetSQlConnectionString & " | " ST1.Items(2).Text = DbConect.GetSrvName ST1.Items(1).Text = DbConect.GetConnectionState & " | "
End Sub
و الكود التالي في زر الحفظ
PHP كود :
'اجراء الحفظ Private Sub SaveBtn_Click(sender As Object, e As EventArgs) Handles SaveBtn.Click Me.Validate() bn1.EndEdit() bn2.EndEdit() bn3.EndEdit()
Dim SaveDataSet As New DataSet SaveDataSet = ds.Clone
If ds.HasChanges = True Then SaveDataSet = ds.GetChanges(DataRowState.Added Or DataRowState.Deleted Or DataRowState.Modified)
If (Not (SaveDataSet) Is Nothing) Then
'*******هذه الاحداث لعرض العمليات و لا دخل لها بعملية الحفظ قم بازالتها AddHandler da3.RowUpdating, AddressOf OnRowUpdating AddHandler da3.RowUpdated, AddressOf OnRowUpdated '*******
da1.Update(SaveDataSet, d1.TableName) da2.Update(SaveDataSet, d2.TableName) da3.Update(SaveDataSet, d3.TableName)
'******** RemoveHandler da3.RowUpdating, AddressOf OnRowUpdating RemoveHandler da3.RowUpdated, AddressOf OnRowUpdated '********
ds.Merge(SaveDataSet) ds.AcceptChanges() End If
End If
End Sub
فقط هذا كل ما احتجناه لعمليات الحفظ مهما كانت العمليات التي تمت على الجداول
انا اضفت حدثين اضافيين لتعرف ما الذي حصل اثناء عملية الحفظ و تحديدا لجدول تفاصيل الفاتورة فقط
PHP كود :
Private Sub OnRowUpdating(sender As Object, e As SqlRowUpdatingEventArgs) PrintEventArgs(e) End Sub
Private Sub OnRowUpdated(sender As Object, e As SqlRowUpdatedEventArgs) PrintEventArgs(e) End Sub
Private Overloads Sub PrintEventArgs(args As SqlRowUpdatingEventArgs)
TextBox1.Text += Environment.NewLine & ("OnRowUpdating") TextBox1.Text += Environment.NewLine & (" event args: (" & " command=" & args.Command.CommandText & " commandType=" & args.StatementType & " status=" & args.Status & ")") End Sub
Private Overloads Sub PrintEventArgs(args As SqlRowUpdatedEventArgs) TextBox1.Text += Environment.NewLine & ("OnRowUpdated") TextBox1.Text += Environment.NewLine & (" event args: (" & " command=" & args.Command.CommandText & " commandType=" & args.StatementType & " recordsAffected=" & args.RecordsAffected & " status=" & args.Status & ")") End Sub
و هذا تجريب من واجهة الادخال
و اخيرا المثال مرفق مع سكربت القاعدة لمن يحب ان يجرب
الجزئية التي تم تعديلها في الكلاس السابق
PHP كود :
Private Shared Sub GetServerList() Dim Server As String = String.Empty Dim instance As Sql.SqlDataSourceEnumerator = Sql.SqlDataSourceEnumerator.Instance Dim table As System.Data.DataTable = instance.GetDataSources() Dim Machine As String = String.Empty
For p As Integer = 0 To table.Rows.Count - 1 Server = String.Empty Server = table.Rows(p).Item("ServerName") If table.Rows(p).Item("ServerName").ToString.Length > 0 Then If table.Rows(p).Item("ServerName") = Machine Then Machine = (System.Environment.MachineName) Server = table.Rows(p).Item("ServerName") ReDim SrvNameArray(table.Rows.Count - 1) SrvNameArray.SetValue(Server, p) Else Machine = (System.Environment.MachineName + "\" + table.Rows(p).Item("ServerName")) ReDim SrvNameArray(table.Rows.Count - 1) SrvNameArray.SetValue(Server, p) End If MsgBox(SrvNameArray.Count) End If Next
End Sub
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - الوادي - 26-06-16
يا ابو ليلى،
أنا اسمي مكتوب؟ طييييييييب.
مجهود رائع ومرتب
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 26-06-16
ايوا مكتوب يا غالي
عبد البصير الملقب بالوادي
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 26-06-16
بارك الله بك اخي خضر و بكل الاخوة الموجودين
RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 28-06-16
السلام عليكم و رحمة الله و بركاته
كنت في هذا الكلاس قد اشرت الى نقطة تخص الكلاس ServSite
و كانت الافضلية لفصل اجراءات السيرفر عن الاجراءات الخاصة بالقاعدة و اجلت الحديث عنها الى حين اكتمال الفكرة لدي
و الفكرة هي انشاء مدير للسيرفر كما هي الحال مع SQL Server Management Studio
و الاستفادة من الكلاس السابق الى اقصى الحدود و تطويره حسب اي اتجاه ترغب فيه
يمكنك التوسع في اي اتجاه تحبه و تفضله كأن تصبح قادراً على انشاء قواعد البيانات و كائناتها المختلفة من خلال الكود او ابتداع المعالج الخاص بك ....الخ
انا احببت التوسع في اتجاهين الى الان
الاتجاه الاول:عرض كل كائنات السيرفر لدي بكل ما تحتويه من قواعد و من جداول و استعلامات و اجراءات و مستخدمين و مجموعات.
الاتجاه الثاني:هو صناعة مدير خاص بالاجراءات المخزنه Stored Procedure , مهمته اعطائك وسيلة ذكية و سريعة لانشاء اي نوع من الاجراءات المعتادة
الاضافة و الحذف و التعديل و الحفظ و استعلامات التحديد بكل اشكالها البسيطة و المعقدة مع فرض كل انواع البارمترات التي توافق الحقول و الكثير الكثير و مازال التوسيع جاريا للخروج بافضل شكل و اسهل استخدام.
الفكرة المستقبلية :هي استغلال كل ما يقدمه SQL Server من امكانية و استغلالها خلال عملنا و خصوصا باب الصلاحيات و الاذونات الخاصة بكل قاعدة و جدول و حقل و فرضها داخل عملنا
لا ادري صراحة ان كنت ساخرج بنتيجة من دراسة هذه الجزئية (الصلاحيات و الاذونات من SQl Server الى داخل اطار العمل) لم اتوفر على مصادر في هذا الاتجاه
ما الغاية من كل هذا العمل ؟؟؟؟ لماذا تعيد اختراع العجلة.
ليس لشيئ كما احب ان اقول دائما لغاية في نفس يعقوب.
اترككم مع الصور الاولية من الاتجاهات التي تحدثت عنها سابقا تم انجازها و الحمد لله تعمل بكفائة عالية , لكن واجهتني مشكلة تبسيط الواجهة لجعلها سهلة الاستخدام
|