PDA

View Full Version : سوال: نحوه چک کردن شرط attach بودن بانک



salehvasaleh
یک شنبه 15 مرداد 1391, 18:20 عصر
اگر بخواهیم در هنگام باز شدن برنامه ابتدا چک شود که بانک موجود در یک درایو خاص ، attach است؟باید این شرط را چطور چک کنیم؟ممنون

hakim22
یک شنبه 15 مرداد 1391, 19:00 عصر
شما ابتدا از common file درون program files کتابخانه SQL server رو اضافه کنید به refrence های پروژه
بعد با استفاده از microsoft.sqlserver.managment می توانید با فراخوانی فرمانهای شاخه SMO همه ی عملیات های معمول با SQL server را از درون کد شبیه سازی کنید.
لیست دیتابیس های Attach شده هم از همین طریق قابل دسترسی است.

sirvan-me
یک شنبه 15 مرداد 1391, 21:09 عصر
میشه بیشتر در مورد این Reference ، کلاس هاش توضیح بدید یا یه Reference و یا نمونه ارائه بدین ؟

salehvasaleh
یک شنبه 15 مرداد 1391, 21:31 عصر
یعنی از طریق کد نویسی راهی وجود نداره که بفهمیم یک بانک در یک مسیر خاص اتچ شده یا خیر؟

nilmil_nil
دوشنبه 16 مرداد 1391, 00:59 صبح
سلام دوست عزیز
نمونه کد SQL 1

DECLARE @dbname nvarchar(128ِ)
SET @dbname = N'Senna'

IF (EXISTS (SELECT name
FROM master.dbo.sysdatabases
WHERE ('[' + name + ']' = @dbname
OR name = @dbname)))


PRINT 'db exists'



نمونه کد دوم

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'YourDatabaseName')
PRINT 'db exists'


البته زیاد فرقی با هم ندان :لبخند:
تو هر دو دستور چک میشه که آیا دیتابیس شما وجود داره یا نه !!!

salehvasaleh
دوشنبه 16 مرداد 1391, 01:15 صبح
سلام دوست عزیز
نمونه کد SQL 1

DECLARE @dbname nvarchar(128ِ)
SET @dbname = N'Senna'

IF (EXISTS (SELECT name
FROM master.dbo.sysdatabases
WHERE ('[' + name + ']' = @dbname
OR name = @dbname)))


PRINT 'db exists'



نمونه کد دوم

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'YourDatabaseName')
PRINT 'db exists'


البته زیاد فرقی با هم ندان :لبخند:
تو هر دو دستور چک میشه که آیا دیتابیس شما وجود داره یا نه !!!
ممنون از پستی که زحمت کشیدید و گذاشتید.ولی یک سوال می شه یکم توضیح بدین که با توجه به نام بانک باید کدوم قسمتهاش تغییر کنه؟ یکم برام گنگ شده ! ممنون

nilmil_nil
دوشنبه 16 مرداد 1391, 02:09 صبح
خواهش میکنم
به جای YourDatabaseName نام بانک رو بنویس تو کد دوم
و تو کد اول به جای Senna نام بانک رو بنویس
و اونو توی سی شارپ اجرا کن :لبخندساده:

salehvasaleh
دوشنبه 16 مرداد 1391, 12:55 عصر
خواهش میکنم
به جای YourDatabaseName نام بانک رو بنویس تو کد دوم
و تو کد اول به جای Senna نام بانک رو بنویس
و اونو توی سی شارپ اجرا کن :لبخندساده:
از توضیحتون ممنون یعنی باید من همچین کدی بنویسم؟ کجاش ناقص هست؟بعد از if باید چی بنویسم؟
اسم بانک من d هست.




string str;
str = "Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
con.Open();
if
{
SqlCommand comm = new SqlCommand("name FROM d.databases WHERE name = N'd'", con);
PRINT 'db exists';
}



می دونم این کد قطعا یک جاهاییش ایراد داره اگه میشه راهنمایی کنید. / این خط رو که اصلا نمی شناسه.

PRINT 'db exists';

شرط if رو هم نم دونم چی باید بنویسم.

sirvan-me
دوشنبه 16 مرداد 1391, 13:44 عصر
دوست من کد هایی که آقای nil.... دادن برای اجرا تو محیط SQL SERVER نوشته شدن ... شما باید به صورت Query به SQL SERVER بفرستی و جواب بگیری و مثلا اون دستور PRINT و باید خودت تو محیط Visual Studio با دستور :

Console.Write("Db Exist");

بنویسی

در ضمن شما تو Query تون Select رو جا انداختی .... جای Sys.Database هم نباید اسم دیتابیس خودتو بنویسی .

salehvasaleh
دوشنبه 16 مرداد 1391, 13:51 عصر
دوست من کد هایی که آقای nil.... دادن برای اجرا تو محیط SQL SERVER نوشته شدن ... شما باید به صورت Query به SQL SERVER بفرستی و جواب بگیری و مثلا اون دستور PRINT و باید خودت تو محیط Visual Studio با دستور :

Console.Write("Db Exist");

بنویسی

در ضمن شما تو Query تون Select رو جا انداختی .... جای Sys.Database هم نباید اسم دیتابیس خودتو بنویسی .
ممنون یعنی من این کد رو بنویسم درسته؟



SqlCommand comm = new SqlCommand("SELECT name FROM sys.databases WHERE name = N'd'", con);

sirvan-me
دوشنبه 16 مرداد 1391, 13:59 عصر
شما از این کد استفاده کن ... من تست کردم : ( اگر result مقدار true بود یعنی دیتابیس وجود داره )

جای databaseName اسم دیتابیس مورد نطرتو بنویس ... و اگر از SqlExpress استفاده می کنی ConnectionString رو هم تغییر بده

string sqlCreateDBQuery;
bool result = false;

try
{
SqlConnection tmpConn = new SqlConnection("server=(local);Trusted_Connection=yes");

sqlCreateDBQuery = String.Format("SELECT database_id FROM sys.databases WHERE Name = '{0}'", databaseName);

using (tmpConn)
{
using (SqlCommand sqlCmd = new SqlCommand(sqlCreateDBQuery, tmpConn))
{
tmpConn.Open();
int databaseID = (int)sqlCmd.ExecuteScalar();
tmpConn.Close();

result = (databaseID > 0);
}
}
}
catch (Exception)
{
result = false;
}

return result;

hakim22
دوشنبه 16 مرداد 1391, 14:01 عصر
این روش ها بر پایه ی T-SQL هست. خوبی ها و بدی های خودشو داره اما در صورت نیاز به SMO و استفاده از کلاسهای دات نت :
http://msdn.microsoft.com/en-us/library/ms162129.aspx

و
http://msdn.microsoft.com/en-us/library/ms220286

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

salehvasaleh
دوشنبه 16 مرداد 1391, 14:14 عصر
شما از این کد استفاده کن ... من تست کردم : ( اگر result مقدار true بود یعنی دیتابیس وجود داره )

جای databaseName اسم دیتابیس مورد نطرتو بنویس ... و اگر از SqlExpress استفاده می کنی ConnectionString رو هم تغییر بده

string sqlCreateDBQuery;
bool result = false;

try
{
SqlConnection tmpConn = new SqlConnection("server=(local);Trusted_Connection=yes");

sqlCreateDBQuery = String.Format("SELECT database_id FROM sys.databases WHERE Name = '{0}'", databaseName);

using (tmpConn)
{
using (SqlCommand sqlCmd = new SqlCommand(sqlCreateDBQuery, tmpConn))
{
tmpConn.Open();
int databaseID = (int)sqlCmd.ExecuteScalar();
tmpConn.Close();

result = (databaseID > 0);
}
}
}
catch (Exception)
{
result = false;
}

return result;
ضمن تشکر از توضیحتون. یک سوال آیا این کد زیر که شبیه همین کد شماست منطقی هست؟



con.Open();
SqlCommand comm = new SqlCommand("SELECT name FROM sys.databases WHERE name = N'd'", con);

int k = (int)comm.ExecuteNonQuery();

if (k == 1)
{
MessageBox.Show("قبلا اتچ شده");
}
else
{
MessageBox.Show("باید اتچ شود");
}

nilmil_nil
دوشنبه 16 مرداد 1391, 14:34 عصر
از توضیحتون ممنون یعنی باید من همچین کدی بنویسم؟ کجاش ناقص هست؟بعد از if باید چی بنویسم؟
اسم بانک من d هست.




string str;
str = "Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
con.Open();
if
{
SqlCommand comm = new SqlCommand("name FROM d.databases WHERE name = N'd'", con);
PRINT 'db exists';
}



می دونم این کد قطعا یک جاهاییش ایراد داره اگه میشه راهنمایی کنید. / این خط رو که اصلا نمی شناسه.

PRINT 'db exists';

شرط if رو هم نم دونم چی باید بنویسم.

سلام دوست عزیز
ببخشید دیر جواب دادم
این کد باید توی SQLCommand بذارید و اجرا کنید و جواب رو در یک دیتاتیبل بریزید یا با ExecuteScalar اجرا کنید و جواب که برگشت اونوقت چک کنید اگر رشته برگردانده شده برابر با "db exists" بود اونوقت دیتابیس شما در SQL Server وجود داره
یعنی تمام کد هایی که گذاشتم رو در SqlCommand بنویسید ....

salehvasaleh
دوشنبه 16 مرداد 1391, 14:36 عصر
سلام دوست عزیز
ببخشید دیر جواب دادم
این کد باید توی SQLCommand بذارید و اجرا کنید و جواب رو در یک دیتاتیبل بریزید یا با ExecuteScalar اجرا کنید و جواب که برگشت اونوقت چک کنید اگر رشته برگردانده شده برابر با "db exists" بود اونوقت دیتابیس شما در SQL Server وجود داره
یعنی تمام کد هایی که گذاشتم رو در SqlCommand بنویسید ....
سلام و ممنون از لطفتون. اگر کد پست قبلی که نوشتم رو توی محیط سی شارپ بنویسم چطوره؟منطقی هست؟

nilmil_nil
دوشنبه 16 مرداد 1391, 14:41 عصر
آره اینم درسته
من طبق کد SQL که گذاشته بودم برات توضیح دادم

sirvan-me
دوشنبه 16 مرداد 1391, 14:43 عصر
دوست عزیز متد ExecuteScalar میاد اولین ستون از اولین سطر جدول درخواست شده در Query درخواستی رو برمی گردونه .... تو کدی که براتون نوشتم مقدار برگشتی رو می تونیم به نوع Int تبدیل کنیم اما شما تو دستورتون مقدار برگشتیتون از نوع varchar هستش و جواب درستی رو برای شما برنمی گردونه .... اگر می خواید براتون Name رو برگدونه باید شرطتون رو عوض کنید و اینطور بنویسید که اگر نام برگشتی برابر با نام دیتابیسم بود اونوقت دیتابیس هست ...

salehvasaleh
دوشنبه 16 مرداد 1391, 14:53 عصر
دوست عزیز متد ExecuteScalar میاد اولین ستون از اولین سطر جدول درخواست شده در Query درخواستی رو برمی گردونه .... تو کدی که براتون نوشتم مقدار برگشتی رو می تونیم به نوع Int تبدیل کنیم اما شما تو دستورتون مقدار برگشتیتون از نوع varchar هستش و جواب درستی رو برای شما برنمی گردونه .... اگر می خواید براتون Name رو برگدونه باید شرطتون رو عوض کنید و اینطور بنویسید که اگر نام برگشتی برابر با نام دیتابیسم بود اونوقت دیتابیس هست ...
ممنون از توضیحتون. یعنی باید بجای executenonquery از ExecuteScalar استفاده کنم؟؟ ولی فک کنم باید یک تغییری توش بدم که شما گفتید و من هنوز متوجه نشدم میشه لطف کنید بگید اگه بخوام با همیسن سبک کدی که نوشتم این دستور رو عملی کنم باید چه تغییری توی کد بدم؟ممنون

salehvasaleh
دوشنبه 16 مرداد 1391, 19:26 عصر
دوست عزیز متد ExecuteScalar میاد اولین ستون از اولین سطر جدول درخواست شده در Query درخواستی رو برمی گردونه .... تو کدی که براتون نوشتم مقدار برگشتی رو می تونیم به نوع Int تبدیل کنیم اما شما تو دستورتون مقدار برگشتیتون از نوع varchar هستش و جواب درستی رو برای شما برنمی گردونه .... اگر می خواید براتون Name رو برگدونه باید شرطتون رو عوض کنید و اینطور بنویسید که اگر نام برگشتی برابر با نام دیتابیسم بود اونوقت دیتابیس هست ...
اگر کدها رو این طوری بنویسم درسته؟ من این کد رو نوشتم ولی بازم جواب نمی ده و ایرادی که در عکس هست رو می ده:
http://bsl.site40.net/pic/25eaeac5bef3.jpg



bool result = false;
string str;
str = "Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
con.Open();
SqlCommand comm = new SqlCommand("SELECT name FROM sys.databases WHERE name = N'd'", con);
int k = (int)comm.ExecuteScalar();
result = (k > 0);


// if (k == 1)
if(result==true)
{
MessageBox.Show("قبلا اتچ شده");
}
else
{
string strr;
strr = "Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
SqlConnection conn = new SqlConnection(strr);
conn.Open();
SqlCommand comm2 = new SqlCommand("EXECUTE sp_attach_db @dbname,@filename1,@filename2", conn);
comm2.Parameters.Add("@dbname", SqlDbType.VarChar, 260).Value = "d";
comm2.Parameters.Add("@filename1", SqlDbType.VarChar, 260).Value = "E:\\bank\\d.mdf";
comm2.Parameters.Add("@filename2", SqlDbType.VarChar, 260).Value = "E:\\bank\\d_log.ldf";
comm2.ExecuteNonQuery();
MessageBox.Show("اتچ شد");
}

sirvan-me
دوشنبه 16 مرداد 1391, 23:22 عصر
اگر کدها رو این طوری بنویسم درسته؟ من این کد رو نوشتم ولی بازم جواب نمی ده و ایرادی که در عکس هست رو می ده:
http://bsl.site40.net/pic/25eaeac5bef3.jpg



bool result = false;
string str;
str = "Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
con.Open();
SqlCommand comm = new SqlCommand("SELECT name FROM sys.databases WHERE name = N'd'", con);
int k = (int)comm.ExecuteScalar();
result = (k > 0);


// if (k == 1)
if(result==true)
{
MessageBox.Show("قبلا اتچ شده");
}
else
{
string strr;
strr = "Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
SqlConnection conn = new SqlConnection(strr);
conn.Open();
SqlCommand comm2 = new SqlCommand("EXECUTE sp_attach_db @dbname,@filename1,@filename2", conn);
comm2.Parameters.Add("@dbname", SqlDbType.VarChar, 260).Value = "d";
comm2.Parameters.Add("@filename1", SqlDbType.VarChar, 260).Value = "E:\\bank\\d.mdf";
comm2.Parameters.Add("@filename2", SqlDbType.VarChar, 260).Value = "E:\\bank\\d_log.ldf";
comm2.ExecuteNonQuery();
MessageBox.Show("اتچ شد");
}


دوست من ، گفتم که شما چون مقدار برگشتیتون ( Name ) از طریق اجرا دستور SELECT از نوع عددی نیست اگر هم بتونین اون رو به نوع int تبدیل کنید جواب صحیح نمیگیرین ... پس شما به جای تبدیل به int ... تو شرط چک کنید که مقدار برگشتی ( بعد از تبدیل به string از طریق تابع ToString ) برابر با نام دیتابیسی که جهت تعیین موجودیت به SQL SERVER پاس دادین هست یا نه .....

sirvan-me
دوشنبه 16 مرداد 1391, 23:23 عصر
حالا چه اصراریه که کدها رو تغییر بدین ... کد که کار می کرد ؟!!!!!!!!!

salehvasaleh
سه شنبه 17 مرداد 1391, 00:57 صبح
حالا چه اصراریه که کدها رو تغییر بدین ... کد که کار می کرد ؟!!!!!!!!!
پس به این حساب باید از همون کدهای شما استفاده کنم درسته؟یعنی طبق همون ساختارو بنویسم؟
با توجه به این که من نام بانک d هست باید چه تغیری در کد شما بدم؟!

salehvasaleh
سه شنبه 17 مرداد 1391, 01:20 صبح
دوست من ، گفتم که شما چون مقدار برگشتیتون ( Name ) از طریق اجرا دستور SELECT از نوع عددی نیست اگر هم بتونین اون رو به نوع int تبدیل کنید جواب صحیح نمیگیرین ... پس شما به جای تبدیل به int ... تو شرط چک کنید که مقدار برگشتی ( بعد از تبدیل به string از طریق تابع ToString ) برابر با نام دیتابیسی که جهت تعیین موجودیت به SQL SERVER پاس دادین هست یا نه .....
ممنون حالا متوجه شدم اما بازم یک جای کارم می لنگم کدو ببینید:


SqlConnection con = new SqlConnection(str);
con.Open();
sqlCreateDBQuery = string.Format("SELECT name FROM sys.databases WHERE name = N'd'", con);
if(sqlCreateDBQuery =????)
{
MessageBox.Show("قبلا اتچ شده");
}


کدهایی که نوشتم درستند؟چطوری باید شرط رو بنویسم که اگه برابر نام پایگاه که d هست اگه برابر بود پیغام بده اتچ شده؟

salehvasaleh
سه شنبه 17 مرداد 1391, 12:32 عصر
دوست من ، گفتم که شما چون مقدار برگشتیتون ( Name ) از طریق اجرا دستور SELECT از نوع عددی نیست اگر هم بتونین اون رو به نوع int تبدیل کنید جواب صحیح نمیگیرین ... پس شما به جای تبدیل به int ... تو شرط چک کنید که مقدار برگشتی ( بعد از تبدیل به string از طریق تابع ToString ) برابر با نام دیتابیسی که جهت تعیین موجودیت به SQL SERVER پاس دادین هست یا نه .....
آقا دمت گرم مشکل حل شد فهمیدم اشکال کجاست شما زودتر گفتی من تازه فهمیدم ! واقعا ممنون. یک سوال در نوشتن SqlConnection در مقابل Catalog من باید اسم بانکم رو بنویسم یا کلمه master ؟


SqlConnection tmpConn = new SqlConnection("Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True");

یا


SqlConnection tmpConn = new SqlConnection("Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=d;Integrated Security=True");

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

sirvan-me
سه شنبه 17 مرداد 1391, 18:59 عصر
آقا دمت گرم مشکل حل شد فهمیدم اشکال کجاست شما زودتر گفتی من تازه فهمیدم ! واقعا ممنون. یک سوال در نوشتن SqlConnection در مقابل Catalog من باید اسم بانکم رو بنویسم یا کلمه master ؟


SqlConnection tmpConn = new SqlConnection("Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True");

یا


SqlConnection tmpConn = new SqlConnection("Data Source=SABZIANP-509BB1\\SQLEXPRESS;Initial Catalog=d;Integrated Security=True");

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

نیازی نیست نام دیتابیس خاصی رو ذکر کنید ....

salehvasaleh
چهارشنبه 18 مرداد 1391, 18:06 عصر
نیازی نیست نام دیتابیس خاصی رو ذکر کنید ....
یعنی مقابل کاتلوگ چیی ننویسم؟می شه بگید چطور کدی منظورتونه؟ممنون

sirvan-me
چهارشنبه 18 مرداد 1391, 21:09 عصر
دوست من شما کدی که من بهتون دادم و دقیق خوندید ؟!!!!!!