PDA

View Full Version : آموزش: رفع مشکل BackUp و Restor از بانک SQL برای همیشه + نمونه برنامه



amir200h
چهارشنبه 23 مرداد 1392, 17:07 عصر
سلام به همه دوستان.
با این قضیه واقعا خیلی ها مشکل دارن و جوابی هم که واقعا به نتیجه برسه من تو فروم پیدا نکردم و راه حل هایی که دوستان گفته بودن یه جاهایی مشکل داشت.
امیدوارم که با این آموزش مشکل برای همیشه حل بشه و دیگه کسی واسه این موضوغ تاپیک نزنه.
خوب واسه شروع یه پروژه باز کنین و ابزارهای زیرو به فرمتون اضاقه کنید
txtAddress: برای ذخیره آدرس مکانی که میخواهیم فایل پشتیبان اونجا گرفته بشه یا بخوایم بانکو بازیابی کنیم
btnAddAddress: برای انتخاب محل مناسب برای پشتیبان گیری و بازیابی
btnBakcUp: برای پشتیبان گیری
btnRestor: برای بازیابی
نام بانک: amir200h

خوب برای شروع ما نیاز به 4تا تابع داریم. یکی برای گرفتن پشتیبان و یکی هم برای بازیابی بانک.
یکی هم برای انتخاب کردن بانک از محل خاص و آخری هم برای انتخاب مکانی برای ذخیره.

اول میریم سراغ تابعی که برای انتخاب مکانی برای گرفتن پشتیبانه میریم
این تابع پنجره savedialog رو باز میکنه و آدرسی محلی که انتخاب کردین رو برمیگردونه
private string setSave()
{
var savedDialog1 = new SaveFileDialog();
string strFileName = string.Empty;
savedDialog1.DefaultExt = "BAK";
savedDialog1.FileName = "BackupFile" + DateTime.Now.ToShortDateString();
savedDialog1.Filter = @"SQL Backup files (*.BAK) |*.BAK|All files(*.*) |*.*";
savedDialog1.FilterIndex = 1;
savedDialog1.OverwritePrompt = true;
savedDialog1.Title = "Backup SQL File";
if (savedDialog1.ShowDialog() == DialogResult.OK)
{
strFileName = savedDialog1.FileName;
}
else
{
return string.Empty;
}
return strFileName;
}

خوب حالا برای btnAddAdress کد های زیرو میزاریم.
باید تابع setSave رو صدا کنیم تا یک مکان انتخاب کنیم و آدرس اونو بریزیم داخل txtaddress
برای این کار از کد زیر استفاده میکنیم
txtAddress.Text = setSave();
خوب حالا باید بریم سراغ نوشتن تابع برای پشتیبان گیری.
تابع پشتیان گیری یک پارامتر داره و اون هم آدرس مکانی برای گرفتن پشتیبانه.
private void Backup(string strFileName)
{
try
{
if (strFileName != string.Empty)
{
string command = @"BACKUP DATABASE amir200h TO DISK='" + strFileName + "'";
var oConnection = new SqlConnection("server=(local);database=amir200h;trusted_connectio n=yes");
if (oConnection.State != ConnectionState.Open)
oConnection.Open();
var oCommand = new SqlCommand(command, oConnection);
oCommand.ExecuteNonQuery();
MessageBox.Show(@"ok");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
خوب حالا میریم سراغ نوشتن کد برای btnBackUp
خوب ما میایم مقدار txtaddress رو میدیم به تابع BackUp تا فایل پشتیبان اونجا گرفته بشه
چون ممکنه کاربر جایی را برای ذخیره کردن انتخاب نکرده باشه و مستقیم روی این دکمه کلیک کنه ما میایم چک میکنیم که اگه txtAddress خالی بود بیاد تابع setSave رو صدا بزن و مقدارشو پاس بده به تابع BackUp تا عملیات انجام بشه.
کدش خیلی ساده س
private void btnBackUp_Click(object sender, EventArgs e)
{
Backup(txtAddress.Text == string.Empty ? setSave() : txtAddress.Text);
}

خوب تا اینجا واسه backup یا همون پشتیبان گیری.

حالا میریم سراغ resore یا همون بازیابی

اول باید ی تابع بنویسیم که پنجره opendialog رو باز کنه تا بتونیم فایل پشتیبان خودمون رو انتخاب کنیم
برای این کار تابع زیرو مینویسیم
private string loadAddress()
{
var openFileDialog1 = new OpenFileDialog();
string strFileName;
openFileDialog1.Filter = @"SQL Backup files (*.BAK) |*.BAK|All files(*.*) |*.*";
openFileDialog1.FilterIndex = 1;
openFileDialog1.Title = "Restore SQL File";
switch (openFileDialog1.ShowDialog())
{
case DialogResult.OK:
strFileName = openFileDialog1.FileName;
break;
default:
return string.Empty;
}
return strFileName;
}
این تابع هم آدرس جایی رو که انتخاب کردیم برمیگردونه
خوب بریم سراغ تابعی که عملیات restore را قراره انجام بده.
برای اینکار یه تابع مینویسیم که یه پارامتر میگیره و اون هم آدرس فایل پشتیبانمونه که با تابع بالا بدست میاریم
private void Restore(string strFileName)
{
try
{
if (strFileName != string.Empty)
{
string command = "ALTER DATABASE amir200h SET OFFLINE with ROLLBACK IMMEDIATE RESTORE DATABASE amir200h FROM DISK = '" + strFileName + "'" +
" WITH REPLACE";
var oConnection = new SqlConnection("Data Source=(local);database=amir200h;Integrated Security=SSPI");
if (oConnection.State != ConnectionState.Open)
oConnection.Open();
var oCommand = new SqlCommand(command, oConnection);
oCommand.ExecuteNonQuery();
MessageBox.Show(@"ok");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
نکته ای که باید بگم در مورد کوئری این تابع س که اکثر دوستان تا اینجای کار میان ولی اینجا به مشکل های مختلفی بر میخورن. برای بازیابی بانک 2تا راه داریم اول اینکه باید تمام کانکشن هایی که به بانک وصله س رو قطع کنیم یا اینکه برنامه رو کلا ببندیم و تو ی برنامه جداگانه عملیات پشتیبان رو انجام بدیم. که روش دوم اصلا درست نیست و غیر حرفه ایه. من روش اولو میگم. تو کوئری بالا ما ابتدا میایم بانکمون رو آفلاین میکنیم و وقتی که آفلاین شد در واقع تمام کانکشن ها بهش قطع میشه و ما به راحتی عملیات بازیابی رو انجام میدیم.

خوب حالا میریم سراغ باتن btnrestore
دقیقا مثل باتن BackUpه فقط تابع loadaddress و restore رو فراخوانی میکنیم به این صورت
private void btnRestor_Click(object sender, EventArgs e)
{
Restore(txtAddress.Text != string.Empty ? txtAddress.Text : loadAddress());
}
به همین سادگی به همین خوشمزه گی :لبخند:
پروژه هم ضمیمه کردم که ماکلا تست شده