# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > VB.NET >  atatch یا detatch کردن دیتابیس از sql server در محیط  وی بی دات نت

## programmermp

با سلام

من می خواهم کار atatch یا detach کردن دیتابیس رو که در سیستم مقصد باید به صورت

دستی انجام بشه به کد نویسی در محیط وی بی دات نت انجام بدم یعنی یک دکمه بزارم

که وقتی کلیک شد کار atatch دیتابیس به sql و یک دکمه دیگر برای detatch کردن دیتابیس

از sql رو انجام بده

در ضمن نمی دونم  می  تونم این کار رو بکنم  که از دیتابیسم یک backup بگیرم و بعد 

دیتابیسم رو توی کامپیوتر مقصد restore کنم

این طور ی مشکلی ایجاد نمی شه

لطفا راهنمای کنید


با تشکر

----------


## Asad.Safari

اینو یه نگاه بنداز (البته تو سی شارپ هست):


 void InitializeServer()
        {
            // To Connect to our SQL Server - we Can use the Connection from the System.Data.SqlClient Namespace.
            SqlConnection sqlConnection = new SqlConnection(@"Integrated Security=SSPI; Data Source=(local)\SQLEXPRESS;");

            //build a "serverConnection" with the information of the "sqlConnection"
            Microsoft.SqlServer.Management.Common.ServerConnec  tion serverConnection = new Microsoft.SqlServer.Management.Common.ServerConnec  tion(sqlConnection);

            //The "serverConnection is used in the ctor of the Server.
            server = new Server(serverConnection);
         //   MessageBox.Show(server.State.ToString());

           
        }

        private void attachButton_Click(object sender, EventArgs e)
        {
            try
            {
                InitializeServer();
                StringCollection c = new StringCollection();
                c.Add(@''c:\beautysalon.mdf'');
               

               server.AttachDatabase("beautysalon", c);
           }
         }

----------


## programmermp

با تشکر از جوابتون

ولی نتونستم از کد شما استفاده کنم چون وی بی خطا می داد که مثلا

microsoft.sqlserver.management  همچین چیزی وجود نداره در کتابخانه sqlserver

دوستان دیگه اگه لطف کنند کمک کنند ممنون میشم

در ضمن از روشی که خودم در پست اول گفتم (بازیابی نسخه پشتیبان روی سیستم مقصد)

نمی شه استفاده کرد چون اولا باید بررسی بشه که دیتابیس هست از قبل یا نه

که  من بلد نیستم این کار رو بکنم و چون بلد نیستم ممکنه از قبل دیتابیس و جود داشته 

باشه و با بازیابی من اطلاعات دیتابیس از بین بره 

لطفا کمک کنید

----------


## programmermp

یکی به ما هم جواب بده 

خداییش نمی دونم  چکار کنم :تشویق:   :تشویق:   :تشویق:

----------


## programmermp

سلام 


یک مثال براش از توی سایت planet-source -code.com پیدا کردم که با sp کار میکنه

اینجا می زارم که کسایی که می خوان استفاده کنند 

ولی اگه کسی بلده این کار رو بدون sp و در محیط وی بی با کد انجام بده یک چیزی مشابه

کاری که در پست قبلی دوستمون گفت به من هم بگه 

با تشکر

----------


## mostafa_leman

کد Attach کردن با VB.NET :



Imports System.Data.SqlClient
Public Class FrmAttachDB
    Dim constatus As Boolean = False
    Dim con As SqlConnection

    Private Sub FrmAttachDB_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If My.Computer.FileSystem.DirectoryExists("C:\databas  e") = False Then
            My.Computer.FileSystem.CreateDirectory("C:\Databas  e")
        End If
        DropDatabase()
        CopyDB()
        AttachDB()
        Me.Close()
    End Sub

    Function AttachDB() As Boolean
        ConOpen()
        Dim cmd As New SqlCommand()
        Dim txt As String

        txt = "sp_attach_db @dbname = N'MyDatabase', " & vbCrLf & _
              "@filename1 = N'C:\Database\MyDatabase.MDF', " & vbCrLf & _
              "@filename2 = N'C:\Database\MyDatabase_log.LDF'"

        cmd.CommandText = txt
        cmd.Connection = con
        cmd.ExecuteNonQuery()
    End Function

    Public Sub ConOpen()
        Try
            constatus = True
            con = New SqlConnection("Data Source=.;Initial Catalog=master;Integrated Security=True")
            con.Open()
        Catch ex As Exception
            constatus = False
        End Try
    End Sub
    Function DropDatabase() As Boolean
        Dim cn As New SqlClient.SqlConnection
        cn.ConnectionString = _
         "Server=localhost;" & _
         "DataBase=Master;" & _
         "Integrated Security=SSPI;" & _
         "data source=(local)"
        Dim CreateDBCommand As New SqlClient.SqlCommand
        CreateDBCommand.Connection = cn
        CreateDBCommand.CommandText = "IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = N'MyDatabase') " & _
        "DROP DATABASE [MyDatabase]"
        cn.Open()
        Try
            CreateDBCommand.ExecuteNonQuery()
        Catch Ex As Exception
        End Try
        cn.Close()
        Return True
    End Function
    Function CopyDB() As Boolean
        My.Computer.FileSystem.CopyFile(My.Application.Inf  o.DirectoryPath + "\Database\MyDatabase.mdf", "C:\Database\MyDatabase.mdf", True)
        My.Computer.FileSystem.CopyFile(My.Application.Inf  o.DirectoryPath + "\Database\MyDatabase_log.ldf", "C:\Database\MyDatabase_log.ldf", True)
    End Function
End Class

----------


## mostafa_leman

فایلهای MDF و LDF فایل را باید در یک فولدر به نام Database در کنار برنامه قرار دهید

----------


## programmermp

با سلام و تشکر فراوان از شما اقا مصطفی

اما یک سئوال پیش اومده برام اونم اینه که تابع drop Database چه کار می کنه

اگه اشتباه نکنم کار بررسی وجود دیتابیس در sql server رو انجام می ده که اگه 

وجود داشته باشه دیتابیس رو حذف می کنه 

خواب اینطوری اگه کاربر برای دوم بخواهد برنامه رو نصب بکنه یعنی بعد از حذف برنامه 

بخواهد دوباره ان را نصب کند برنامه چک می کنه می بینه دیتابیس از قبل هست و بعد 

دیتابیس رو حذف می کنه اینطوری تمام اطلاعات قبلی از بین می ره که

فکر کنم اگه کد حذف دیتابیس رو بشه یک جوری تغییر داد که به جای حذف جدول از 

attach کردن جدول جلوگیری کنه خیلی خوب می شه

اگه امکانش هست یه توضیحی در این مورد بدید 


با تشکر

----------


## mostafa_leman

درسته . ببینید شما می تونید اینجا به کاربر یک پیغام بدید که برنامه دیتا بیسی رو که قبلا ساخته شده رو پیدا کرده .  آیا میخواهید از این اطلاعات استفاده کنید یا اینکه میخواهید بانک اطلاعاتی صفر شود؟
اگه میخواست صفر بشه که خوب کدش رو نوشتم اما اگه میخواست از اون اطلاعات استفاده کنه
2 حالت پیش میاد : 
یکی اینکه اون فایلها فقط وجود فیزیکی دارند و در بانک اطلاعاتی Attach نشده اند ( مثلا ویندوز پاک شده یا Sql Server پاک شده ) که در این صورت باید ابتدا این دو فایل رو از اون فولدر به یک شاخه Temp کپی کنید . سپس از اون آدرس این فایلها رو Attach کنید و سپس اون فایلها و فولدر Temp رو حذف کنید
یا اینکه اون فایلها قبلا Attach شده اند و هنوز در Sql Server اونا رو تو لیست بانکهاش داره . اینجا کار یکم سخت میشه . چون Sql Server اجازه کپی گرفتن از فایل رو نمیده و باید ابتدا Sql Server رو Stop کنیم و سپس یک کپی از فایلها در یک شاخه Temp بگیریم و سپس Sql Server رو Start کنیم و اون دیتابیس رو Drop کنیم و دیتابیسی را که در شاخه Temp کپی کرده ایم Attach کنیم . از آخر فولدر Temp رو به همراه محتویاتش حذف کنیم 
این راهیه که به ذهنم میرسه . . .

----------


## Mehrafrooz

ببخشید یک سوال هم برای من پیش اومده و اونم اینکه با فرض اینکه attach کردن دیتا بیس رو به درستی انجام بدیم ولی قبلش باید کنترل کنیم که این دیتابیس ، همون دیتابیس مورد نظر ماست و کاربر به اشتباه دیتا بیس دیگه ای رو attach نکنه . برای این کار چی پیشنهاد میدید ؟
ممنون .

----------


## mostafa_leman

منظورتونو واضح نفهمیدم .ما واسه اینکه مطمئن بشیم همون دیتا بیس هست باید نام دیتابیس رو چک میکنیم
اگه میشه منظور سوالتونو بگین

----------


## mostafa_leman

البته در جواب آقای Programmerp باید بگم هنگامی که فایلها قبلا Attach شده اند و هنوز در Sql Server اونا رو تو لیست بانکهاش داره . نیازی به Attach دوباره نیست . برنامه میتونه از همون بانک استفاده کنه

----------


## programmermp

> ببخشید یک سوال هم برای من پیش اومده و اونم اینکه با فرض اینکه attach کردن دیتا بیس رو به درستی انجام بدیم ولی قبلش باید کنترل کنیم که این دیتابیس ، همون دیتابیس مورد نظر ماست و کاربر به اشتباه دیتا بیس دیگه ای رو attach نکنه . برای این کار چی پیشنهاد میدید ؟
> ممنون .


سلام 

اقای مهر افروز سئوالی که من مطرح کردم بدین معنی بود که برنامه خودش بتونه 

وجود یا عدم وجود دیتابیس رو تشخیص بده و کار attach رو خودش براساس نتیجه بدست

امده انجام بده یا نده نه اینکه کاربر این کار رو بکنه

اصلا هدف من از طرح این تاپیک این بود که کار کاربر رو کم کنم نه اینکه یه کد بنویسم که

کاربر بتونه attach کنه چون در حالت عادی هم بدون نیاز به کد خودمون این کار رو می تونیم

دستی انجام بدیم

----------


## programmermp

> البته در جواب آقای Programmerp باید بگم هنگامی که فایلها قبلا Attach شده اند و هنوز در Sql Server اونا رو تو لیست بانکهاش داره . نیازی به Attach دوباره نیست . برنامه میتونه از همون بانک استفاده کنه


اقا مصطفی من هم دقیقا همین هدف رو دنبال می کردم و می خواستم با کدی که 

شما دادید وجود یا عدم وجود دیتابیس رو چک کنیم در sql server و بر اساس اون به برنامه

بگم که کار attach رو انجام بده یا نده

با تشکر

----------


## Mehrafrooz

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

----------


## mostafa_leman

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


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

----------


## programmermp

دقیقا مصطفی جان یک راهش اینه

حتی می تونه یک پوشه ایجاد بکنه تحت عنوان dbbackup و توی openfiledialog متد

مربوط به پوشه پیش فرض رو که اگه اشتباه نکنم initial directory هست برابربا اون مسیر 

قرار بده و باز هم حتی می تونه با default ext پسوندش رو به عنوان پیش فرض انتخاب کنه

که نیاز به انتخاب هم نداشته باشه

----------


## Mehrafrooz

> دقیقا مصطفی جان یک راهش اینه
> 
> حتی می تونه یک پوشه ایجاد بکنه تحت عنوان dbbackup و توی openfiledialog متد
> 
> مربوط به پوشه پیش فرض رو که اگه اشتباه نکنم initial directory هست برابربا اون مسیر 
> 
> قرار بده و باز هم حتی می تونه با default ext پسوندش رو به عنوان پیش فرض انتخاب کنه
> 
> که نیاز به انتخاب هم نداشته باشه


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

----------


## mostafa_leman

این چیزی که شما میگید احتمالش زیر یک درصد . درسته؟

----------


## Mehrafrooz

> این چیزی که شما میگید احتمالش زیر یک درصد . درسته؟


درسته . ولی احتمالش هست حتی یک درصد .

----------


## mostafa_leman

اگه بخوای محکم کاری کنی باید یک sp بنویسی که وجود هر Table رو توی دیتابیست چک کنه

----------


## programmermp

مصطفی جان سلام

برای این چک کردن جداول که گفتی stored procedure باید بنویسیم چطوری می شه 

یعنی چطوری باید نوشت می شه از همون کد هایی که برای چک کردن وجود دیتابیس در 

اس کیو ال سرور داده بودی استفاده کرد یا نه

یه راهنمایی کنی ممنون می شم 

با تشکر

----------


## Mehrafrooz

برای مقایسه دو دیتابیس این رو ببینید :
http://www.codeproject.com/useritems...aseCompare.asp

----------


## komail_sh

میشه از refrence  microsoft sqldmo استفاده کرد و با یک خط کد این کار رو انجام داد .
sqldmo.attach
sqldmo.detach

----------


## programmermp

> میشه از refrence microsoft sqldmo استفاده کرد و با یک خط کد این کار رو انجام داد .
> sqldmo.attach
> sqldmo.detach


دوست عزیز 

همه اینو می دونن ولی بحث تاپیک رو اگه یه نگاه بندازی روی مشخص کردن وجود یا عدم

وجود دیتابیس از قبل در sql server هست که sql dmo این کار رو نمی تونه انجام بده

----------


## komail_sh

sql server لیست دیتا بیس ها و مشخصات اونها رو توی دیتابیس مستر و جدول sysdatabase ذخیره میکنه .
شاید بشه از اونم کمک گرفت
در ضمن برای وجود ویا عدم وجود هم میتوان از همین جدول استفاده کرد

----------


## programmermp

چجوری کسی می تونه راهنمایی بکنه در زمینه استفاده از systemdatabase

----------


## mostafa_leman

IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = N'MYDatabase')

----------


## ehsan_ansaripoor

با سلام به همه دوستان
           شرمنده این سوال را می پرسم آخه من تازه از VB به VB.Net اومدم می خواستم بدونم برای طراحی Table و Query در محیط VB2005 به غیر از Sql Server که از طریق Visual Studio نصب میشه احتیاج به نصب چیزه دیگه ای هم هست.
           خواهشا توضیح بدید.

----------


## programmermp

سلام

sql server که همراه وی بی نصب می شه express هست و فقط موتور محسوب می شه

یعنی رابط کاربر یا user interface برای کار نداره یعنی هیچ محیط خاصی واسه طراحی 

نداره

شما باید یکی از نسخه های اس کیو ال سرور رو تهیه و نصب کنی مثل

desktop engine
developer
personal
enterprise
که من خودم از developer استفاده می کنم از طریق فروشگاه سایت هم فکر کنم بشه

تهیه کرد من که خودم اینطوری تهیه کردم

----------


## yavari

سلام

من از کد آقا مصطفی استفاده میکنم این خطا رو میده !
CREATE DATABASE permission denied in database 'master'.
ممنون میشم یکی بگه چجوری رفع میشه !

با احترام

----------


## yavari

سلام

من هنوز مشکلم حل نشده !

----------


## mostafa_leman

شما با استفاده از این برنامه بانک اطلاعاتی رو attach میکنید و این یعنی اینکه یک دیتابیس جدید ساخته میشه و چون این sp در دیتابیس master اجرا میشه و شما اجازه ی ساخت دیتابیس جدید رو از این دیتابیس گرفتین این پیغام ظاهر میشه . یا این اجازه رو به دیتابیس master بدین یا اینکه connectionstring اونو به دیتابیس northwind تغییر بدین

----------


## vahab2010

اقا مصطفي ميشه يه لطفي كنيد و بگيد كجا بايد ادرس فايل هاي ldfو mdf ام رو بنويسم بانك من نه mastere و نه northwindبانك بانكيه كه خودم طراحي كردم

----------

