تقييم الموضوع :
  • 1 أصوات - بمعدل 5
  • 1
  • 2
  • 3
  • 4
  • 5
الغزل مع SQL Server
#1
السلام عليكم و رحمة الله و بركاته
طالما مثل SQL Server الحل الافضل بالنسبة للمبرمجين لما يحويه من خصائص كثيرة و قوة كبيرة في التعامل مع قواعد البيانات و تعدد المستخدمين و الحل الامثل لبرامج الشبكات باختلاف انواعها.
لكن بقيت المشكلة الكبيرة بالنسبة لنا هي كثرة المشاكل التي نقع فيها بسبب جهلنا في التعامل معه و قلة المصادر التعليمية .
اهم تلك المشاكل غالبا كانت تتمثل في دعم الاصدارات الحديثة لقواعد بيانات منشئة تحت اصدارات سابقة او حتى ربطها , او زرعها و حقنها ضمن اصدارات احدث.
كل تلك المشاكل و غيرها حاول المبرمجون التغلب عليها بالابتعاد عن التعامل مع SQL Server بشكل مباشر و لجؤوا للتعامل مع لغة SQL المعيارية في انشاء قواعدهم تحت اي نسخة SQL Server , طالما كانت كل الاصدارات تدعم هذه اللغة , و هي طريقة جيدة و فعالة في التعامل مع SQL Server مهما كانت نسخته و تؤدي الغرض المطلوب منها .

هدفي هو ليس التعامل مع هذه اللغة المعيارية ضمن بيئة العمل , ففي الاصدارات الحديثة من SQL Server تم دعم هذه المحركات بشكل اكبر ضمن بيئة العمل و اصبح التعامل معها اسهل مما كان عليه في السابق , و اصبحت الكائنات الخاصة به مدعومة بشكل اكبر و تؤدي الغرض المطلوب منها بشكل كامل , مع انها كانت مدعومة في بيئات العمل السابقة مثل VB6 مثلا , و الذي كان يدعم محرك قواعد البيانات SQL Server 2000 و ما قبله ضمن بيئته , و كنا نستخدم كائن SQLDmo في التواصل مع المحرك و الولوج الى كائناته و التعامل معها .
لكن الامر اختلف مع الاصدارات الحديثة من SQL Server و بيئة DotNet , فمنذ الاصدار 2005 اصبح الكائن الجديد في التعامل مع هذا المحرك هو كائن SQLSmo و هذا الكائن الجديد اصبح مدعوما بشكل اكبر من الكائن السابق و التعامل معه اقوى بكثير .
ساقوم في هذا الموضوع بمناقشة بعض المشاكل و عرض الحلول لها , و مناقشة التعامل مع الكائن الجديد SQLSmo في التواصل مع مخدم قواعد البيانات SQL Server , و التي تتضمن اهم النقاط التي نحتاجها مثل:
- عرض السيرفرات المثبة على الجهاز .
-طريقة الدخول للسيرفر سواء كان دخول امن , او دخول تحت اسم مستخدم و كلمة مرور .
-عرض المستخدمين في السيرفر.
-عرض قواعد البيانات في السيرفر , و طرق انشاء قواعد البيانات فيه.
-عرض كائنات قاعدة البيانات (الجداول - الاستعلامات-الاجراءات المخزنة و غيرها)
-طرق انشاء قواعد البيانات و كائناتها , و لكن ليس باستخدام الطريقة التقليدية , اذا ان SQL Server يدعم طرق الانشاء باستخدام السكربتات التي يتم توليدها تلقائيا عند عمل اي كائن في السيرفر و هي طريقة فعالة جدا و لا تحتاج لاي جهد (كل ما ستحتاجه هو سكربت لاي كائن , قاعدة بيانات او جدول او غيره ) ثم اعطاء الامر للسيرفر ليقوم بتنفيذ السكربت .
-انشاء صورة لقاعدة البيانات و استرجاعها كذلك , مع الاشارة الى اختلاف نسخة المخدم كون بعض المشاكل تحدث عند محاولة استرجاع صورة لقاعدة بيانات انشئت تحت اصدار سابق الى قاعدة بيانات منشئة تحت اصدار حديث.

كل هذه الخطوات سيتم التعامل معها ضمن VB.Net ان شاء الله.
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال
الرد }}}
#2
بسم الله الرحمن الرحيم


في البداية
للذين يحبون التطبيق المباشر متابعة الخطوات لاننا سنخرج في النهاية بمشروع او شبه مشروع يخدمنا في التعامل و يسهل مهامنا . Cool
لنتوكل على الله و نبدأ

افتح VS و قم بانشاء مشروع جديد من النوع Windows Forms
لدينا الان FOrm1 ضمن المشروع  نضيف بعض الادوات

-ListBox نسميها LstSrv
-TextBox نسميه TxtSrvName
-TextBox نسميه txtLogin
-TextBox نسميه txtPassword
-RadioButton نسميه chkWindowsAuthentication
-Button نسميه btnConnect

الخطوات التي سنقوم بعملها هي فحص السيرفرات المثيته على الجهاز و عرضها في LstSrv
اذا كان هناك سيرفرات طبعا
و بعدها سنحتاج للاتصال بالسيرفر المحدد باحدى الطريقتين اما باستخدام آمان وندوز او باستخدام اسم مستخدم و كلمة مرور.

ساقوم بعمل اجراء جديد نسميه LoadServ

PHP كود :
Private Sub LoadServ()
 
       'تحميل السيرفرات الموجودة على الجهاز
        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
                    LstSrv.Items.Add(System.Environment.MachineName)

                Else
                    LstSrv.Items.Add(System.Environment.MachineName + "\" + element)

                End If
            Next
        End If

    End Sub 


الكود السابق سيقوم بالبحث ضمن سجل الجهاز عن اي سيرفر مثبت سواء كان نسخة Express أو اي نسخة اخرى و اضافتها الى Lstsrv

بعد توفر السيرفرات لدينا سنحاول الاتصال بها كما اسلفنا
اولا ساقوم باضافة بعض الخطوات التاكيدية للنظر فيما اذا كان هناك سيرفرات تم ادخالها الى LstSrv , و ان المستخدم قد اختار احد السيرفرات بالفعل و كذلك التاكد من نوع الاتصال لنبدأ بكتابة الاكواد

PHP كود :
If LstSrv.Items.Count <= 0 Then
            MessageBox
.Show("لا يوجد سيرفرات مثبتة على الجهاز""تسجيل الدخول"MessageBoxButtons.OKMessageBoxIcon.InformationMessageBoxDefaultButton.Button1MessageBoxOptions.RightAlign)

 
           Exit Sub
        ElseIf LstSrv
.Items.Count And TxtServName.Text "" Then
            MessageBox
.Show("يرجى تحديد السيرفر""تسجيل الدخول"MessageBoxButtons.OKMessageBoxIcon.InformationMessageBoxDefaultButton.Button1MessageBoxOptions.RightAlign)

 
           Exit Sub
        End 
If


 
       If chkWindowsAuthentication.Checked False And txtLogin.Text "" And txtPassword.Text "" Then
            MessageBox
.Show("يرجى تحديد اسم المستخدم و كلمة المرور او استخدام امان وندوز""تسجيل الدخول"MessageBoxButtons.OKMessageBoxIcon.InformationMessageBoxDefaultButton.Button1MessageBoxOptions.RightAlign)

 
           Exit Sub
        End 
If 


اظن ان الاكواد واضحة .

الان ناتي الى عملية الدخول الى السيرفر المحدد.
الان و لكي نعمل مع الكائن SQLSmo الذي تحدثنا عنه سابقا يجب ان نقوم باستيراد بعض المراجع لمشروعنا
وجب التنبيه انه يجب ان يكون لديك نسخة SQL Server مثبة على الجهاز لديك
يختلف موقع المراجع باختلاف نسخة SQL Sever المثبة لديك فقط اتبع ما يلي

النسخة المثبته لدي هي SQL Server 2008 R2
و المراجع المطلوبة موجودة في المسار التالي
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies
الرقم 100 هو خاص برقم النسخة.
في حال كان لديك SQL Sever 2005 ستجد المراجع تحت الرقم 90 على ما اعتقد
ليصبح المسار الخاص بها كما يلي
C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies
و هكذا تجري العملية مع اختلاف النسخ و الله اعلم.
المراجع المطلوبة هي الملفات التالية

Microsoft.SqlServer.ConnectionInfo
Microsoft.SqlServer.Management.Sdk.Sfc
Microsoft.SqlServer.Smo
Microsoft.SqlServer.SmoExtended
Microsoft.SqlServer.SqlEnum
طريقة اضافتها
في تبويب Solution Explorer
قف على References ثم Add Reference و حدد الملفات السابقة ضمن المسار الموجود لديك و الذي تحدده رقم نسخة SQL Server.


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

PHP كود :
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft
.SqlServer.Management.Smo
Imports Microsoft
.SqlServer.Management.Sdk.Sfc 


الان اصبحنا جاهزين للعمل مع الكائن SQLSmo  و التخاطب مع SQL Server .
سنقوم بتعريف بعض المتغيرات التي سنحتاجها للعمل في بداية الكلاس نقوم بتعريف المتغيرات التالية.

PHP كود :
Dim s As String
    Dim conn 
As New ServerConnection()
 
   Dim srv As New Server() 

الان نعود الى زر الاتصال الخاص بنا لنفحص نوع الاتصال الذي قام المستخدم بتحديده
ان كان من النوع آمان وندوز او مشروط باسم مستخدم و كلمة مرور.
في زر الاتصال وتحت الاكواد السابقة التي فحصنا من خلالها تواجد السيرفرات في الجهاز و كذلك فحصنا في ما اذا كان المستخدم قد حدد سيرفراً ليتم الاتصال به
سنقوم بالاتصال بالسيرفر و عرض اسماء المستخدمين و كذلك القواعد المثبتة على السيرفر طبعا ليس قواعد النظام بل قواعدنا التي انشأناها نحن .
سنحتاج لبعض الادوات الجديدة لعرض اسماء المستخدمين و كذلك القواعد

- LstBox نسميها LstDbs  لعرض قواعد البيانات
- ListBox نسميها LstLogin  لعرض المستخدمين

تحت الاكواد السابقة نضيف الكود التالي

PHP كود :
If chkWindowsAuthentication.Checked True Then
            
'اتصال موثوق
            conn = New ServerConnection(LstSrv.SelectedItem.ToString)
            srv = New Server(conn)
            LstDbs.Items.Clear()
            LoadLogins()
            LoadDbs()


        Else
            '
اتصال بكلمة مرور
            conn 
= New ServerConnection(LstSrv.SelectedItem.ToStringtxtLogin.TexttxtPassword.Text)
 
           srv = New Server(conn)
 
           LoadLogins()
 
           LoadDbs()

 
       End If


 
       If srv.ConnectionContext.IsOpen Then
            srv
.ConnectionContext.Disconnect()
 
       End If 


LoadLogins هو الاجراء الخاص بجلب اسماء المستخدمين و نوعهم  و الكود الخاص به كما يلي

PHP كود :
   Private Sub LoadLogins()
 
       For Each lognName As Login In srv.Logins
            If Not lognName
.IsSystemObject Then
                If Not lognName
.Name.Contains("#"Then
                    LstLogin
.Items.Add(lognName.Name " - " lognName.LoginType.ToString)

 
               End If

 
           End If

 
       Next
    End Sub 


اما الاجراء LoadDbs فهو شبيه بالاجراء السابق كما يلي

PHP كود :
   Private Sub LoadDbs()

 
       'تحميل القواعد باستثناء قواعد النظام
        Try
            '
=================
 
           LstDbs.Items.Clear()
 
           Me.Cursor Cursors.WaitCursor

            For Each db 
As Database In srv.Databases
                If Not db
.IsSystemObject Then
                    LstDbs
.Items.Add(db.Name)
 
               End If
 
           Next

        Catch ox 
As SmoException
            MsgBox
(ox.Message.ToString)
 
       Catch ex As Exception
            MsgBox
(ex.Message.ToString)
 
       Finally
            Me
.Cursor Cursors.Default
 
           If srv.ConnectionContext.IsOpen Then
                srv
.ConnectionContext.Disconnect()
 
           End If
 
       End Try

 
   End Sub 


هذا كل ما نحتاجه لعرض المستخدمين و القواعد المثبتة لدينا على السيرفر
اظن ان الاكواد سهلة و لا تحاتج للنقاش و على كل حال اي مشكلة في اي كود يرجى طرح السؤال و ان شاء الله ساقوم بالاجابة عنه.
بقي ان اضيف بعض الاكواد البسيطة لضبط بعض الخصائص هي زيادة في الحرص ليس الا
تابع و سترى
كود تعطيل مربعات النص الخاصة بالدخول في حال اختار المستخدم الدخول وفق آمان وندوز

PHP كود :
   Private Sub chkWindowsAuthentication_CheckedChanged(sender As System.ObjectAs System.EventArgsHandles chkWindowsAuthentication.CheckedChanged
        If chkWindowsAuthentication
.Checked True Then
            txtLogin
.Enabled False
            txtPassword
.Enabled False
        Else
            txtLogin
.Enabled True
            txtPassword
.Enabled True
        End 
If
 
   End Sub 


بهذه الطريقة نكون قد حصلنا على مبتغانا , هناك الكثير من الامور الفنتازية التي يمكنك المرور عليها.
مثلا لعرض اسم ملف قاعدة البيانات المحددة و موقع القاعدة على الجهاز و الاسم الداخلي للقاعدة.
و كذلك عرض خصائص قاعدة البيانات المحددة.
يمكننا ذلك عن طريق كود بسيط و لعمل ذلك اضف بعض الادوات تحت القائمة LstbBs

- TextBox نسميه TextBox1 نعرض فيه اسم ملف قاعدة البيانات الملف من النوع Mdf
- TextBox نسميه TextBox2 نعرض فيه موقع قاعدة البيانات , المسار
- TextBox نسميه TextBox3 سنعرض فيه اسم القاعدة المختارة
- TextBox نسميه TextBox4 نعرض فيه الاسم الداخلي للملف
- ListBox نسميه LstDbProp نعرض فيه خواص القاعدة المحددة

الكود التالي سيفي بالغرض

PHP كود :
Private Sub LstDbs_SelectedIndexChanged(sender As System.ObjectAs System.EventArgsHandles LstDbs.SelectedIndexChanged
        
'تحميل معلومات القاعدة المحددة
        If LstDbs.Items.Count > 0 Then

            TextBox1.Text = ""
            TextBox2.Text = ""
            TextBox3.Text = ""
 TextBox4.Text = ""
LstDbProp.Items.Clear()
 Dim db As Database = srv.Databases(LstDbs.SelectedItem.ToString)
            TextBox3.Text = db.Name
            For Each fg As FileGroup In db.FileGroups
                TextBox1.Text = (fg.Name)


                For Each df As DataFile In fg.Files
                    TextBox2.Text = (df.FileName)
                    TextBox4.Text = df.Name
                Next

            Next
Dim database As Database = srv.Databases(LstDbs.SelectedItem.ToString)
            LstDbProp.Items.Clear()

            For Each prop As [Property] In database.Properties
                LstDbProp.Items.Add(prop.Name + " - " + prop.Value.ToString)
            Next
End If
If srv.ConnectionContext.IsOpen Then
            srv.ConnectionContext.Disconnect()
        End If
End Sub 


و لعرض اسماء الجداول و الاستعلامات و الاجراءات المخزنة سنقوم باضافة بعض الادوات

- ListBox نسميه LstTable لعرض الجداول
- ListBox نسميه LstViews لعرض الاستعلامات
- ListBox نسميه LstStoredPro لعرض الاجراءات
- ListBox نسميه LstTbProp نعرض فيه اسماء الحقول و نوعها الخاصة بالجدول المحدد


الاجراء التالي سيتكفل بالمهمة

PHP كود :
   Private Sub LoadAll()
 
       LstTable.Items.Clear()
 
       LstViews.Items.Clear()
 
       LstStoredPro.Items.Clear()

 
       Dim Dbs As Database srv.Databases(LstDbs.SelectedItem.ToString)
 
       Me.Cursor Cursors.WaitCursor
        
'تحميل الجداول
        Dim myTable As Table

        For Each myTable In Dbs.Tables
            If Not myTable.IsSystemObject Then
                LstTable.Items.Add(myTable.Name)
            End If
        Next
        '
--------
 
       'تحميل المناظر
        Dim myviews As View
        For Each myviews In Dbs.Views
            If Not myviews.IsSystemObject Then
                LstViews.Items.Add(myviews.Name)
            End If
        Next
        '
---------
 
       'تحميل الاجراءات
        Dim myStoredPro As StoredProcedure
        For Each myStoredPro In Dbs.StoredProcedures
            If Not myStoredPro.IsSystemObject Then
                LstStoredPro.Items.Add(myStoredPro.Name)
            End If
        Next

        Me.Cursor = Cursors.Default
    End Sub 


نضيف هذا الاجراء في نهاية الكود السابق ليصبح الكود كما يلي


PHP كود :
Private Sub LstDbs_SelectedIndexChanged(sender As System.ObjectAs System.EventArgsHandles LstDbs.SelectedIndexChanged
        
'تحميل معلومات القاعدة المحددة
        If LstDbs.Items.Count > 0 Then

            TextBox1.Text = ""
            TextBox2.Text = ""
            TextBox3.Text = ""
 TextBox4.Text = ""
LstDbProp.Items.Clear()
LstTbProp.Items.Clear()
 Dim db As Database = srv.Databases(LstDbs.SelectedItem.ToString)
            TextBox3.Text = db.Name
            For Each fg As FileGroup In db.FileGroups
                TextBox1.Text = (fg.Name)


                For Each df As DataFile In fg.Files
                    TextBox2.Text = (df.FileName)
                    TextBox4.Text = df.Name
                Next

            Next
Dim database As Database = srv.Databases(LstDbs.SelectedItem.ToString)
            LstDbProp.Items.Clear()

            For Each prop As [Property] In database.Properties
                LstDbProp.Items.Add(prop.Name + " - " + prop.Value.ToString)
            Next
 LoadAll() '
تحميل الجداول و الاستعلامات و الاجراءات
End 
If
If 
srv.ConnectionContext.IsOpen Then
            srv
.ConnectionContext.Disconnect()
 
       End If
End Sub 



الان اصبحت اغلب مكونات القاعدة لدينا بقي ان نعالج حقول الجدول المحدد و فق الكود التالي

PHP كود :
Private Sub LstTable_SelectedIndexChanged(sender As System.ObjectAs System.EventArgsHandles LstTable.SelectedIndexChanged
        Try

            LstTbProp
.Items.Clear()
 If 
LstTable.Items.Count 0 Then
 
For Each Col As Column In srv.Databases(LstDbs.SelectedItem.ToString).Tables(LstTable.SelectedItem.ToString).Columns
                    LstTbProp
.Items.Add(Col.Name " - " Col.DataType.SqlDataType.ToString)
 
               Next

            End 
If

 
       Catch ex As Exception
            
' MsgBox(ex.Message.ToString)
        End Try 


لدينا الان كل ما نريد استطعنا جلب كائنات القاعدة و كذلك حقول الجدول المحدد .
بعض الامور التي تسترعي انتباهنا ماذا لو احببت ان اشاهد بنية استعلام ما او اجراء مخزن من خلال الكود, يمكننا ذلك و بسهولة , سنضيف بعض الادوات الجديدة.

- TextBox نسميه txtDscr نستخدمه لوصف الكائن المحدد و في اي قاعدة يقبع هذا الكائن
- TextBox نسميه txtBase نستخدمه لعرض ما يحتويه الكائمن من جمل استعلام
- ListBox نسميه lstParameters نستخدمة لعرض البارمترات في حال تم تحديد اجراء مخزن
, عرض اسم الباراميتر و تحديد نوعه.

اما عن الاكواد فهي كما يلي
للحصول على بنية استعلام

PHP كود :
   Private Sub LstViews_SelectedIndexChanged(sender As System.ObjectAs System.EventArgsHandles LstViews.SelectedIndexChanged
        If LstViews
.Items.Count 0 Then
            Try
                txtBase
.Clear()
 
               txtDscr.Clear()
 
               lstParameters.Items.Clear()
 
               Dim myview1 As View srv.Databases(LstDbs.SelectedItem.ToString).Views(LstViews.SelectedItem.ToString)
 
               txtDscr.Text " بنية إستعلام " " - " srv.Databases(LstDbs.SelectedItem.ToString).Name "/" myview1.Name
                txtBase
.Text myview1.TextBody

            Catch ex 
As Exception

            End 
Try
 
       End If
 
   End Sub 


للحصول على بنية اجراء مخزن و عرض البارمترات التي يحتويها

PHP كود :
   Private Sub LstStoredPro_SelectedIndexChanged(sender As System.ObjectAs System.EventArgsHandles LstStoredPro.SelectedIndexChanged
        If LstDbProp
.Items.Count 0 Then
            Try
                txtBase
.Clear()
 
               txtDscr.Clear()
 
               lstParameters.Items.Clear()
 
               Dim stp As StoredProcedure srv.Databases(LstDbs.SelectedItem.ToString).StoredProcedures(LstStoredPro.SelectedItem.ToString)
 
               txtDscr.Text " بنية اجراء مخزن " " - " srv.Databases(LstDbs.SelectedItem.ToString).Name "/" stp.Name
                txtBase
.Text stp.TextBody
                For Each parm 
As Parameter In stp.Parameters
                    lstParameters
.Items.Add(parm.Name " - " parm.DataType.ToString)

 
               Next

            Catch ex 
As Exception

            End 
Try
 
       End If
 
       

    End Sub 


الى هنا نكون قد اكتفينا اليوم , لقائنا يتجدد ان شاء الله لاستكمال بقية المشوار
نستودعكم الله , ولا تنسونا من صالح دعائكم
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال
الرد }}}
#3
السلام عليكم ورحمة الله وبركاته

جزاك الله خيرا وسلمت يداك

استمر اخي العزيز

تحياتي
الرد }}}
تم الشكر بواسطة: ابو ليلى
#4
مرحبا nonoms

وشكرا لك على هالموضوع وعلى هالمجهود الجميل

ولي طلب بسيط لو تكرمت

اخي حاولت امشي معاك بالشرح ولكن تهتConfused

لو ما عليك امر ممكن تنزل السورس كود تبع الدرس

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




سُبْحَانَكَ اللَّهُمَّ وَبِحَمْدِكَ، أَشُهَّدٌ أَنَّ لَا إلَهَ إلا أَنْتَ، أَسَتَغْفِرُكَ وَأَتُوبَ إِلَيْكَ
الرد }}}
تم الشكر بواسطة: ربيع , ابو ليلى
#5
(26-03-14, 06:13 AM)ابو ابراهيم كتب : مرحبا nonoms

وشكرا لك على هالموضوع وعلى هالمجهود الجميل

ولي طلب بسيط لو تكرمت

اخي حاولت امشي معاك بالشرح ولكن تهتConfused

لو ما عليك امر ممكن تنزل السورس كود تبع الدرس

وشكرا لك

اهلا اخي ابو ابراهيم السورس هو هذه الاكواد التي امامك
في نهاية المطاف سيكون لدينا برنامج بسيط يجمع هذه الاكواد
في اي نقطة تهت فقط اسال و نحن نجيب
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال
الرد }}}
تم الشكر بواسطة: ربيع
#6
بسم الله الرحمن الرحيم
السلام عليكم و رحمة الله و بركاته
نستكمل اليوم مشوارنا .
سنتحدث اليوم عن طريقة  انشاء صورة و استرجاعها.
اولا سابدأ بطريقة إنشاء صورة لقاعدة البيانات التي يتم تحديدها في صندوق القواعد .
نضيف بعض الادوات على المشروع , الصورة التالية توضح هذه الادوات.

  1. TextBox نسميه TextBox3
  2. TextBox نسميه folderpath
  3. TextBox نسميه txtrestorename
  4. Button نسميه  Button2
  5. Button نسميه  Button3
  6. Button نسميه  Button4
  7. ProgressBar نسميه ProgressBar1



عمل صورة Backub

يمكننا كائن Backub المشمول ضمن SqlSmo  من إنشاء صورة لقاعدة البيانات.
الكائن Backub يحوي عدة خصائص يمكنك استعراضها بعد انشاء نسخة من هذا الكائن بالطريقة التالية.

كود :
Dim backup As New Backup()


بعد انشاء نسخة من الكائن انت بحاجة الى تحديد نوع العنصر و اسمه وهي هنا قاعدة البيانات و اسمها.
و كما يمكننا التقاط حدث المعالجة (اقصد شريط
Progress ) الخاص بـــ SqlServer ليدلنا على ان العملية قد تمت او لا.
لنبدأ بأعطاء معلومات لكائن Backub كما يلي:

كود :
Dim database As Database = srv.Databases(LstDbs.SelectedItem.ToString)
           Dim backup As New Backup()
           backup.Action = BackupActionType.Database
           backup.Database = database.Name


بعد ذلك نحن بحاجة لتحديد مسار الصورة و نوعها.
انوه هنا على انني استخدمت الكائن
FolderBrowserDialog ليقوم المستخدم بتحديد المسار يدويا.
بامكانك سحب الكائن من صندوق الادوات او تعريفه ضمن الكود و التعامل معه,انا اضفته من صندوق الادوات.
اضف عنصر
FolderBrowserDialog  و سميه FolderBkBros , او قم بتعريفه على حسب رغبتك.
الان علينا معالجة بعض الامور البسيطة لان الغاية من الكائن
FolderBrowserDialog هو فتح مستعرض المجلدات
للبحث عن صور قواعد البيانات من النوع (*.bak) التي سننشأها لاحقا و كذلك الاحتفاظ بالمسار المفتوح و تخزينه في اعدادات البرنامج
ليفتح كل مرة على اخر مسار تم حفظه.
لذلك وجب علي ان اضيف متغير من النوع النصي لاعدادات البرنامج.
اذهب الى خصائص المشروع ثم الى التبويب
Settings و اضف متغير نصي من النوع String و سميه BrowseBk
و اعطيه القيمة (D:\) و هو المسار الافتراضي الذي سيفتح عليه المستعرض لاول مرة ثم بعد ذلك سيتبدل و يحتفظ بالقيمة الجديدة
التي تختارها انت , الصورة التالية توضح المطلوب:



ملاحظة:الطريقة السابقة تفيدك كثيرا في التعامل مع تخزين نصوص الاتصال لقواعد البيانات في حال تغير مسار القاعدة.

بعد ذلك نحن بحاجة للقليل من الكود في حدث النقر على Button3 نكتب ما يلي:

كود :
   Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click

       FolderBkBros.ShowDialog()
       Try
           If Windows.Forms.DialogResult.Yes = Windows.Forms.DialogResult.Yes Then
               folderpath.Text = FolderBkBros.SelectedPath

               My.Settings.BrowseBk = FolderBkBros.SelectedPath
               My.Settings.Save()

               Dim dir As New System.IO.DirectoryInfo(folderpath.Text)
               bkfiles.Items.Clear()

               For Each f As System.IO.FileInfo In dir.GetFiles("*.bak", SearchOption.AllDirectories)
                   bkfiles.Items.Add(f.Name)
               Next

           Else

               Dim dir As New System.IO.DirectoryInfo(folderpath.Text)
               bkfiles.Items.Clear()

               For Each f As System.IO.FileInfo In dir.GetFiles("*.bak", SearchOption.AllDirectories)
                   bkfiles.Items.Add(f.Name)
               Next

           End If


       Catch ex As Exception

       End Try





   End Sub


الكود السابق يقوم بجلب كل ملفات (*.bak) في المسار المحدد و عرضها في قائمة
bkfiles
و الاحتفاظ بالمسار في اعدادات البرنامج كما اسلفنا.

نعود الى الزر
Button2 الذي سيقوم بانشاء صورة لقاعدة البيانات المحددة في مربع النص TextBox3
و يخزنها في المسار الذي حددناه قبل قليل و المعروض في مربع النص folderpath.
الكود التالي سيتكفل بالامر :

كود :
   Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click

       'عمل النسخة الاحتياطية


       If TextBox3.Text.Length > 0 Then
           Dim database As Database = srv.Databases(LstDbs.SelectedItem.ToString)
           Dim backup As New Backup()
           backup.Action = BackupActionType.Database
           backup.Database = database.Name

           If MessageBox.Show(TextBox3.Text & "  انت على وشك عمل نسخة احتياطية للقاعدة  " & vbCrLf & folderpath.Text & " المسار الافتراضي ", "نسخة احتياطية", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2, MessageBoxOptions.RightAlign) = Windows.Forms.DialogResult.Yes Then
               backup.Devices.AddDevice(FolderBkBros.SelectedPath & "\" & Trim(TextBox3.Text) & Date.Now.ToString("dd-MM-yyyy-hh.mm") & ".bak", DeviceType.File)
               ' backup..
               backup.PercentCompleteNotification = 10
               AddHandler backup.PercentComplete, AddressOf Me.ProgressEventHandler

               backup.SqlBackup(srv)

               MessageBox.Show("تمت العملية", "نسخة احتياطية", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
               ProgressBar1.Value = 0

               Try
                   folderpath.Text = FolderBkBros.SelectedPath
                   Dim dir As New System.IO.DirectoryInfo(folderpath.Text)
                   bkfiles.Items.Clear()

                   For Each f As System.IO.FileInfo In dir.GetFiles("*.bak", SearchOption.AllDirectories)
                       bkfiles.Items.Add(f.Name)
                   Next
               Catch ex As Exception

               End Try



           Else
               MessageBox.Show("تم الغاء العملية", "نسخة احتياطية", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
           End If
       Else
           MessageBox.Show("لم يتم تحديد القاعدة", "نسخة احتياطية", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)

       End If

       If srv.ConnectionContext.IsOpen Then
           srv.ConnectionContext.Disconnect()
       End If
   End Sub


اما بالنسبة لمعالجة حدث
percentcomplete فعليك اضافة هذا الاجراء:

كود :
Public Sub ProgressEventHandler(sender As Object, e As PercentCompleteEventArgs)
       Me.ProgressBar1.Value = e.Percent
   End Sub

طبعا انا خزنت اسم القاعدة مع ارسال التاريخ و الساعة و الدقيقة ليكون اسم الصورة اكثر وضوحا.
بهذا اصبح بامكاننا عمل صورة لاي قاعدة بيانات نريدها وفق المسار الذي نحدده.


الاستعادة Restore

كما هو الحال مع كائن Backub يمكننا إنشاء كائن Restore و التعامل مع خصائصه بسهولة
نحتاج الى نوع الملف و اسم الملف و مساره .
التالي كود الزر
Button4 الخاص بالاستعادة.

كود :
   Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
       'الاسترجاع

       If TextBox3.Text = "" Then
           MessageBox.Show("يرجى تحديد اسم القاعدة اولا", "إستعادة النسخة", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
           Exit Sub
       ElseIf txtrestorename.Text = "" Then
           MessageBox.Show("يرجى تحديد نسخة الاسترجاع", "إستعادة النسخة", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
           Exit Sub
       End If

       If MessageBox.Show(TextBox3.Text & "  انت على وشك عمل إستعادة صورة للقاعدة  " & vbCrLf & txtrestorename.Text & " إسم ملف الصورة " & vbCrLf & "يرجى التاكد من تطابق الاسماء", "إسترجاع نسخة", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2, MessageBoxOptions.RightAlign) = Windows.Forms.DialogResult.Yes Then

           Try

               Dim database As Database = srv.Databases(LstDbs.SelectedItem.ToString)
               Dim restore As New Restore()
               restore.Action = RestoreActionType.Database
               restore.Devices.AddDevice(FolderBkBros.SelectedPath & "\" & bkfiles.SelectedItem.ToString, DeviceType.File)
               restore.Database = database.Name
               restore.PercentCompleteNotification = 10
               AddHandler restore.PercentComplete, AddressOf Me.ProgressEventHandler
               restore.ReplaceDatabase = True
               restore.SqlRestore(srv)
               MessageBox.Show("تمت العملية", "إستعادة النسخة", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
           Catch exSMO As SmoException
               MessageBox.Show(exSMO.ToString())
           Catch ex As Exception
               MessageBox.Show(ex.ToString())
           Finally
               Me.ProgressBar1.Value = 0
               If srv.ConnectionContext.IsOpen Then
                   srv.ConnectionContext.Disconnect()
               End If
           End Try


       Else
           MessageBox.Show("تم إالغاء عملية الإستعادة", "إستعادة النسخة", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)

       End If

   End Sub


لم يختلف عن الكود السابق كثيرا  بهذا الشكل نكون اصبحنا قادرين على استعادة اي نسخة لاي قاعدة.


اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال
الرد }}}
#7
إنشاء قاعدة بيانات باستخدام SQLSMO

كنت قد اشرت سابقا في بداية الموضوع عن طريق انشاء قواعد البيانات و كائناتها عن طريق SCRIPT الذي يولده
SqlServer لكل كائنات قاعدة البيانات و حتى قاعدة البيانات نفسها .
الكثير من المبرمجين يستخدمون بيئة
Power Shell وهو برنامج محمل بشكل افتراضي ضمن نظام التشغيل Windows 7
و كذلك ضمن Windows Server 2008 R2  , النسخة الموجودة هي PowerShell 2.0 ويمكنك الحصول على النسخة الثالثة
من هذا الرابط .

http://msdn.microsoft.com/en-us/library/hh847837.aspx

هو برنامج شبيه بمحرر الدوس الافتراضي الموجود مع الوندوز , لكن هذا الاخير مبني بشكل كامل على بيئة
NET Framework common language runtime CLR
على كل الاحوال لست بصدد شرحه هنا يمكنك الاطلاع على معلومات اكثر عنه في الرابط التالي.

http://technet.microsoft.com/en-us/libra...57337.aspx

او يمكنك استخدام
SqlServer لتنفيذ السكربتات الخاصة بك.
ساشرح طريقة إنشاء سكربت و كذلك  تنفيذ سكربت عن طريق
SqlServer بشكل مبسط
فهدفي ليس استخدام
SqlServer بل استخدام بيئة .Net
نتابع وفق الصورة :



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


ملفات السكربت تحمل اللاحقة
*.sql و شكلها كما بالصورة.



لدي ملف سكربت لقاعدة بيانات
NorthWind المشهورة و هي غير موجودة بشكل افتراضي مع
SqlServer 2008 R2 .
ساقوم بتنفيذ السكربت من داخل
SqlServer .
كل ما علي فعله هو فتح الملف ثم تنفيذ السكربت و ها هي القاعدة اصبحت لدينا.



مرفق ملف السكربت الخاص بــ NorthWind

إنشاء قاعدة بيانات باستخدام SQLSMO

نعود لموضوعنا .
نحتاج لبعض الادوات كما بالصورة

  1. Button نسميه Button1  نستخدمه لانشاء القاعدة
  2. Button نسميه DbBros  نستخدمه لاستعراض مكان التخزين
  3. TextBox نسميه txtdbname نستخدمه لاعطاء اسم للقاعدة
  4. TextBox نسميه txtDbPath نستخدمه لعرض المسار


كما فعلنا سابقا سيكون لدينا كائن FolderBrowserDialog  لتحديد مكان التخزين.
و سنحتفظ كذلك بمسار التخزين في اعدادات البرنامج كما فعلنا سابقا.
بالرجوع الى الصورة السابقة.



سنعرف متغير جديد من النوع النصي نسميه
BrowseDb
مهمته هو تخزين مسار المستعرض الخاص بانشاء القواعد.
الان نضيف كائن  
FolderBrowserDialog  من صندوق الادوات كما فعلنا سابقاً.
و من ثم في حدث الضغط على
DbBros نحدد مسار حفظ القاعدة كما يلي:

كود :
Private Sub DbBros_Click(sender As System.Object, e As System.EventArgs) Handles DbBros.Click
       FolderDbBros.ShowDialog()

       If Windows.Forms.DialogResult.Yes = Windows.Forms.DialogResult.Yes Then
           txtDbPath.Text = FolderDbBros.SelectedPath
           My.Settings.BrowseDb = FolderDbBros.SelectedPath
           My.Settings.Save()
       End If
   End Sub


بعد تحديد المسار بقي لدينا إعطاء بعض المعلومات الخاصة بالقاعدة
اسم القاعدة و اسم السيرفر
ملفي القاعدة و المخطط
FileGroups (Mdf,Ldf)
و كذلك تحديد حجم القاعدة.
ثم انشاء القاعدة
في حدث الضغط على الزر
Button1

كود :
'انشاء قاعدة بيانات
       If txtdbname.Text = "" Then
           MessageBox.Show("يرجى تحديد اسم لقاعدة البيانات", "إنشاء قاعدة بيانات", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
           txtdbname.Focus()

           Exit Sub
       Else

           Try

               If MessageBox.Show("  سيتم انشاء قاعدة بيانات  " & vbCrLf & FolderDbBros.SelectedPath & " في المسار  ", "إنشاء قاعدة بيانات", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2, MessageBoxOptions.RightAlign) = Windows.Forms.DialogResult.Yes Then
                   Dim database As New Database(srv, Trim(txtdbname.Text))
                   database.FileGroups.Add(New FileGroup(database, "PRIMARY"))
                   Dim dtPrimary As New DataFile(database.FileGroups("PRIMARY"), Trim(txtdbname.Text), FolderDbBros.SelectedPath & "\" & Trim(txtdbname.Text) & ".mdf") ' "E:\Data\MyNewDatabase1.mdf")
                   dtPrimary.Size = 77.0 * 1024.0
                   dtPrimary.GrowthType = FileGrowthType.KB
                   dtPrimary.Growth = 1.0 * 1024.0
                   database.FileGroups("PRIMARY").Files.Add(dtPrimary)

                   Dim logFile As New LogFile(database, "Log", FolderDbBros.SelectedPath & "\" & Trim(txtdbname.Text) & ".ldf")
                   logFile.Size = 7.0 * 1024.0
                   logFile.GrowthType = FileGrowthType.Percent
                   logFile.Growth = 10.0

                   database.LogFiles.Add(logFile)
                   database.Create()
                   database.Refresh()
                   MessageBox.Show("تمت العملية", "إنشاء قاعدة بيانات", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
                   LstDbs.Items.Clear()
                   For Each db As Database In srv.Databases
                       LstDbs.Items.Add(db.Name)
                   Next

               End If
           Catch ox As SmoException
               MsgBox(ox.Message.ToString)
           Catch ex As Exception
               MsgBox(ex.Message.ToString)
           Finally
               If srv.ConnectionContext.IsOpen Then
                   srv.ConnectionContext.Disconnect()
               End If
           End Try


       End If


   End Sub



هكذا نكون اصبحنا قادرين على انشاء قواعد بيانات .
طبعا قواعد البيانات هذه فارغة لا تحتوي على كائنات مثل الجداول و غيرها.
لن اناقش طريقة انشاء الكائنات الاخرى باستخدام كائن
SQLSMO
سيكون انشائها عن طريق السكربت كما اسلفنا سابقاً.


الملفات المرفقة
.rar   Northwind.rar (الحجم : 822 بايت / التحميلات : 220)
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال
الرد }}}
#8
السلام عليكم ورحمة الله وبركاته

جزاكم الله خيرا مقال مفيد

تحياتي
الرد }}}
تم الشكر بواسطة: ربيع , ابو ليلى
#9
ممــتع بــارك الله فيـــك ~~!I!



[صورة مرفقة: g5qidgW.jpg]

ســبحــانك الـلهم بـحمدك , الـلهم لا عــلم لـنا الى مــأ علــمتــنا , الـلهـم علــمنـا ما جــهلـنا وانــفـعنــا بــما عــلمــتنـا انــك انـتَ الـسـميع الــعلــيم الـحكـيم ~~!I!

الرد }}}
تم الشكر بواسطة: ربيع , ابو ليلى
#10
يعطيك العافية

على

الطرح الرائع
الرد }}}
تم الشكر بواسطة: ربيع , ابو ليلى



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم