پشتیبان گیری از دیتا بیس

saeedasp

Member
سلام خدمت دوستان
پروژه ای به زبان سی شارپ دارم مینویسم که در مورد پشتیبان گیری آن به مشکی برخوردم
وقتی کاربر اطلاعات را ثبت میکند در هنگام خروج از نرم افزار پیغامی گذاشتم که آیا مایل به پشتیبان گیری هستید یا نه اگر شخص بله را بزند به فرمی میرود که با مسیردهی میتواند یک فایل بک آپ بسازد ولی مشکل اینجاس که کاربر با پیغام اینکه دیتابیس در حال استفاده است و امکان کپی گرفتن از آن وجود ندارد. حالا اگر کاربر چیزی را ثبت نکند و به فرم بک آپ گیری برود این اخطار نمی آید کد پشتیبان گیری را هم در زیر گذاشتم
کد:
public partial class Backup : Form
    {
        public Backup()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(textBox1.Text))
            {
                string myAppPath = Directory.GetCurrentDirectory();
                PersianCalendar persia = new PersianCalendar();
                string mydate = persia.GetYear(DateTime.Now).ToString() + "." + persia.GetMonth(DateTime.Now).ToString() + "." + persia.GetDayOfMonth(DateTime.Now).ToString();
                DirectoryInfo drinfo = new DirectoryInfo(textBox1.Text + @"\" + mydate);
                drinfo.Create();
                File.Copy(myAppPath + @"\Database1.mdf",drinfo+ @"\back1.yas",true);
                File.Copy(myAppPath + @"\Database1_log.ldf",drinfo+ @"\back2.yas",true);
                MessageBox.Show("تهيه نسخه پشتيبان با موفقيت انجام شد", "Backup System", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Application.Exit();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog ofd = new FolderBrowserDialog();
            DialogResult dr = ofd.ShowDialog();
            if (dr == DialogResult.OK)
            {
                textBox1.Text = ofd.SelectedPath;
            }
        }

        private void Backup_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.Exit();
        }
    }
 

the_king

مدیرکل انجمن
سلام خدمت دوستان
پروژه ای به زبان سی شارپ دارم مینویسم که در مورد پشتیبان گیری آن به مشکی برخوردم
وقتی کاربر اطلاعات را ثبت میکند در هنگام خروج از نرم افزار پیغامی گذاشتم که آیا مایل به پشتیبان گیری هستید یا نه اگر شخص بله را بزند به فرمی میرود که با مسیردهی میتواند یک فایل بک آپ بسازد ولی مشکل اینجاس که کاربر با پیغام اینکه دیتابیس در حال استفاده است و امکان کپی گرفتن از آن وجود ندارد. حالا اگر کاربر چیزی را ثبت نکند و به فرم بک آپ گیری برود این اخطار نمی آید کد پشتیبان گیری را هم در زیر گذاشتم
کد:
public partial class Backup : Form
    {
        public Backup()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(textBox1.Text))
            {
                string myAppPath = Directory.GetCurrentDirectory();
                PersianCalendar persia = new PersianCalendar();
                string mydate = persia.GetYear(DateTime.Now).ToString() + "." + persia.GetMonth(DateTime.Now).ToString() + "." + persia.GetDayOfMonth(DateTime.Now).ToString();
                DirectoryInfo drinfo = new DirectoryInfo(textBox1.Text + @"\" + mydate);
                drinfo.Create();
                File.Copy(myAppPath + @"\Database1.mdf",drinfo+ @"\back1.yas",true);
                File.Copy(myAppPath + @"\Database1_log.ldf",drinfo+ @"\back2.yas",true);
                MessageBox.Show("تهيه نسخه پشتيبان با موفقيت انجام شد", "Backup System", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Application.Exit();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog ofd = new FolderBrowserDialog();
            DialogResult dr = ofd.ShowDialog();
            if (dr == DialogResult.OK)
            {
                textBox1.Text = ofd.SelectedPath;
            }
        }

        private void Backup_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.Exit();
        }
    }

قبل از اینکه از فایل های بانک اطلاعاتی نسخه کپی بگیرید اول باید detach اش کنید تا فایل هاش آزاد بشه وگرنه بهشون دسترسی ندارید.
کد:
        private void DetachDatabase(string databaseName, string serverName)
        {
            try
            {
                StringBuilder connectionString = new StringBuilder();
                connectionString.AppendFormat("Data Source=\"{0}\";", serverName);
                connectionString.AppendFormat("Initial Catalog=\"{0}\";", "master");
                connectionString.AppendFormat("Integrated Security={0};", "true");
                connectionString.AppendFormat("Connect Timeout={0};", 15);
                using (SqlCommand command = new SqlCommand("", new SqlConnection(connectionString.ToString())))
                {
                    if (command.Connection.State == ConnectionState.Closed)
                    {
                        command.Connection.Open();
                    }
                    command.CommandText = String.Format("EXEC sys.sp_detach_db \"{0}\"", databaseName);
                    command.ExecuteNonQuery();
                }
            }
            catch
            {
            }
        }

مثلا :
کد:
            DetachDatabase("YourDatabaseName", @".\SQLEXPRESS");
 
آخرین ویرایش:

saeedasp

Member
وقتی این کد رو میزنم میگه این دیتابیس در سیستم نیست لطفا با sys.databasesتمام پایگاه داده ها رو ببینید.
اگر امکانش هست راه دیگه ای اگه هست برای پشتیبان گیری رو بگید
 

the_king

مدیرکل انجمن
وقتی این کد رو میزنم میگه این دیتابیس در سیستم نیست لطفا با sys.databasesتمام پایگاه داده ها رو ببینید.
اگر امکانش هست راه دیگه ای اگه هست برای پشتیبان گیری رو بگید
روش تون ایرادی نداره، کاملا درسته.

1) سرور انتخاب شده (serverName) مطابق همونی باشه که برای اتصال عادی به بانک اطلاعاتی بکار می برید.
2) نام بانک اطلاعاتی (databaseName) با نام داخلی بانک اطلاعاتی مطابقت داشته باشه، در ضمن نوع اتصال به بانک
اطلاعاتی هم در نام بانک اطلاعاتی موثره :
در بانک اطلاعاتی هایی که بصورت Attach To File اتصال برقرار میشه (عبارت AttachDbFilename در ConnectionString شون هست)
نام بانک اطلاعاتی ای که موقع Attach شدن ثبت میشه مسیر فایل ئه، نه نام داخلی بانک اطلاعاتی، مثلا میشه "C:\MyApp\Database\MyDB.MDF"

اگه متن داخل رشته ConnectionString ای که برای اتصال به بانک اطلاعاتی تون بکار می برید رو ببینم بهتر می تونم راهنمایی تون کنم.
 

saeedasp

Member
بیشتر جاهای نرم افزار از Entity Framework استفاده کردم ولی جاهایی هم بوده که از روش sqlconnection اینجور چیزا استفاده کردم که مسیر connection هم از app.config میگیرم
که مسیرش اینه
کد:
Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True
اگه چیز دیگه ای هم لازمه بگم بگید تا عرض کنم خدمتتون
در ضمن همون طور که گفتید یه کلاس ساختم اما باز هم همون خطا رو میده حتی با تغییر نام دیتابیس به|DataDirectory|.DataBase1.mdf در قسمت ورودی آرگومان متد.
 
آخرین ویرایش:

the_king

مدیرکل انجمن
بیشتر جاهای نرم افزار از Entity Framework استفاده کردم ولی جاهایی هم بوده که از روش sqlconnection اینجور چیزا استفاده کردم که مسیر connection هم از app.config میگیرم
که مسیرش اینه
کد:
Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True
اگه چیز دیگه ای هم لازمه بگم بگید تا عرض کنم خدمتتون
در ضمن همون طور که گفتید یه کلاس ساختم اما باز هم همون خطا رو میده حتی با تغییر نام دیتابیس به|DataDirectory|.DataBase1.mdf در قسمت ورودی آرگومان متد.

این متد باید مشکل تون رو حل کنه، لیست بانک اطلاعاتی که الان attach شده اند رو بررسی می کنه، هم برای اسم فایل جستجو می کنه و هم اسم بانک اطلاعاتی :
کد:
        private void DetachDatabase(string databaseName, string databaseFilename, string serverName)
        {
            try
            {
                StringBuilder connectionString = new StringBuilder();
                connectionString.AppendFormat("Data Source=\"{0}\";", serverName);
                connectionString.AppendFormat("Initial Catalog=\"{0}\";", "master");
                connectionString.AppendFormat("Integrated Security={0};", "true");
                connectionString.AppendFormat("Connect Timeout={0};", 15);
                using (SqlCommand command = new SqlCommand("", new SqlConnection(connectionString.ToString())))
                {
                    if (command.Connection.State == ConnectionState.Closed)
                    {
                        command.Connection.Open();
                    }
                    using (SqlDataAdapter adapter = new SqlDataAdapter(
                        "SELECT [name] FROM sys.databases", command.Connection))
                    {
                        using (DataTable table = new DataTable())
                        {
                            adapter.Fill(table);
                            foreach (DataRow row in table.Rows)
                            {
                                if ((row[0].ToString().IndexOf(databaseFilename, StringComparison.OrdinalIgnoreCase) >= 0)
                                    || (row[0].ToString().Equals(databaseName, StringComparison.OrdinalIgnoreCase)))
                                {
                                    try
                                    {
                                        command.CommandText = String.Format("EXEC sys.sp_detach_db \"{0}\"", row[0]);
                                        command.ExecuteNonQuery();
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
            }
        }

مثلا :
کد:
            DetachDatabase("Database1", "Database1.mdf", @".\SQLEXPRESS");
 

saeedasp

Member
یه سوالی داشتم اگه بخوام پروژه ای بنویسم که روی sql server 2008 پایگاه دادش رو ساختم آیا حتما باید sql server رو به عنوان پک نرم افزاری که نوشتم ارائه بدم و داخل اون پایگاه دادمو ایمپورت کنم؟ و این که این کارها رو که یک کاربر عادی بلد نیست!و یه چیز دیگه که چون امکانات کسترده ای که داره قابل مقایسه با sql server express خود visual studio نیست
لطفا کمی راهنماییم کنین
 

the_king

مدیرکل انجمن
یه سوالی داشتم اگه بخوام پروژه ای بنویسم که روی sql server 2008 پایگاه دادش رو ساختم آیا حتما باید sql server رو به عنوان پک نرم افزاری که نوشتم ارائه بدم و داخل اون پایگاه دادمو ایمپورت کنم؟ و این که این کارها رو که یک کاربر عادی بلد نیست!و یه چیز دیگه که چون امکانات کسترده ای که داره قابل مقایسه با sql server express خود visual studio نیست
لطفا کمی راهنماییم کنین

روی سیستم باید SQL Server 2008 یا SQL Server Express 2008 نصب باشه، فرقی نمی کنه که کدوم یکی شون. در کنار Setup نرم افزار تون Setup یکی از اونها
رو قرار بدید. حقیقتا SQL Server و SQL Server Express برای بکارگیری در نرم افزار هایی که کاربر مبتدی دارند طراحی نشده اند. برای نرم افزار های بزرگ و
چند کاربره و تحت Server ای طراحی شده اند که اصولا کسی نصب شون می کنه متخصص این کاره. اگه کاربری که نصب شون می کنه تخصصی در این مورد نداره
در انتخاب نوع بانک اطلاعاتی اشتباه صورت گرفته.

برای نرم افزار هابی که از SQL Server استفاده می کنند خیلی مهمه که به کاربر این امکان رو بدید که ConnectionString زو تغییر بده، شما می توانید در کد برنامه تان
دستور SQL ای بنویسید که بانک اطلاعاتی به Server موجود Attach بشه.
 

saeedasp

Member
سلام آیا این روش از نظر جناب عالی برای پشتیبان گیری صحیح میباشد؟
ابته شما راه خوبی را ارائه دادید اما این روش رو هم امتحان کردم یک خطا مبنی بر اینکه این دیتا بیس وجود ندارد را میدهد لطفا راهنماییم کنید
این هم مسیر پایگاه داده Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Talar.mdf;Integrated Security=True;User Instance=True
کد:
[LEFT]           try
            {
                string myAppPath = Directory.GetCurrentDirectory();
                PersianCalendar persia = new PersianCalendar();
                string mydate = persia.GetYear(DateTime.Now).ToString() + "." + persia.GetMonth(DateTime.Now).ToString() + "." + persia.GetDayOfMonth(DateTime.Now).ToString();
                DirectoryInfo drinfo = new DirectoryInfo(textBox1.Text + @"\" + mydate);
                drinfo.Create();
                SqlConnection con = new SqlConnection(talartest.Properties.Settings.Default.TalarConnectionString);
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = @"BACKUP DATABASE Talar TO DISK = '" + textBox1.Text + @"\" + mydate + "\\talar.mdf" + "'";
                cmd.Connection = con;
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
                MessageBox.Show("successfully backup!");
            }
            catch(SqlException ex)
            {
                MessageBox.Show("fail to backup!"+ex.Message);

            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog ofd = new FolderBrowserDialog();
            DialogResult dr = ofd.ShowDialog();
            if (dr == DialogResult.OK)
            {
                textBox1.Text = ofd.SelectedPath;
            }
        }[/LEFT]

 

the_king

مدیرکل انجمن
سلام آیا این روش از نظر جناب عالی برای پشتیبان گیری صحیح میباشد؟
ابته شما راه خوبی را ارائه دادید اما این روش رو هم امتحان کردم یک خطا مبنی بر اینکه این دیتا بیس وجود ندارد را میدهد لطفا راهنماییم کنید
پیغام خطا مشخص و واضحه، بانک اطلاعاتی ای با نام Talar به سرور Attach نشده. قبلا در این مورد توضیح دادم :
در بانک اطلاعاتی هایی که بصورت Attach To File اتصال برقرار میشه (عبارت AttachDbFilename در ConnectionString شون هست)
نام بانک اطلاعاتی ای که موقع Attach شدن ثبت میشه مسیر فایل ئه، نه نام داخلی بانک اطلاعاتی، مثلا میشه "C:\MyApp\Database\MyDB.MDF"
 

m.h.124

Member
با سلام
پروژه من تقریبا کامله. اما بخش بکاپ گیری خیلی اذیتم کرده.میتونم به جرات بگم همه کدهای اینترنت رو امتحان کردم ولی هیچ کدوم کار نمی کردن.آخرین کد کار کرد ولی چه کار کردنی... .بعد از اون چند بار پروژه ام بالا نیومد. دیتابیسم هم اولش با لا نیومد ولی بعد از چند بار بالا اومد در حالیکه کنار اسم دیتابیسم، یک عکس (شبیه عکس انسان) بود.موضوع را به نویسنده ی اون سایت گفتم و با راهنمایی ایشون دیتابیسم مثل حالت اول شد.ایشون گفتن در صورتی می تونم از اون کد استفاده کنم که یک بار دیگه sql server را نصب کنم و تنظیماتش رارو حالت رمزدار بگذارم.من هم چون موقع اولین نصب خیلی اذیت شده بودم گفتم دیگه بخش بکاپ گیری رو بر میدارم از پروژه ام .ولی چون پروژه ام پروژه ی کارشناسیم هست، باید کامل باشه و بدون بکاپ، ناقصه.
به نظر شما راهی هست که بدون نصب دوباره، بکاپ تهیه کنم؟
برای ستاپ سازی، مشکلی پیش نمیاد؟(منظورم با همین نحوه ی ورود به دیتابیسم هست که در عکس می بینید)
من دیتابیسم را در حالت لوکال ساختم.به صورت زیر
attachment.php
attachment.php

ببخشید خیلی طولانی شد.
 

پیوست ها

  • sql.png
    sql.png
    87.5 کیلوبایت · بازدیدها: 5
آخرین ویرایش:

جدیدترین ارسال ها

بالا