Это кажется довольно тривиальным, но это теперь расстраивает меня.
Я использую C# с Экспрессом SQL Server 2005 года.
Я использую следующий код. Я хочу проверить, существует ли база данных прежде, чем создать его. Однако возвращенное целое число-1, и это - то, как MSDN определяет то, что ExecuteNonQuery () возвратит также. Прямо сейчас база данных действительно существует, но она все еще возвращается-1. Однако как я могу сделать эту работу для получения желаемого результата?
private static void checkInventoryDatabaseExists(ref SqlConnection tmpConn, ref bool databaseExists)
{
string sqlCreateDBQuery;
try
{
tmpConn = new SqlConnection("server=(local)\\SQLEXPRESS;Trusted_Connection=yes");
sqlCreateDBQuery = "SELECT * FROM master.dbo.sysdatabases where name =
\'INVENTORY\'";
using (tmpConn)
{
tmpConn.Open();
tmpConn.ChangeDatabase("master");
using (SqlCommand sqlCmd = new SqlCommand(sqlCreateDBQuery, tmpConn))
{
int exists = sqlCmd.ExecuteNonQuery();
if (exists <= 0)
databaseExists = false;
else
databaseExists = true;
}
}
}
catch (Exception ex) { }
}
Начиная с SQL Server 2005, sysobjects
и sysdatabases
и эти представления каталога устарели. Сделайте это вместо этого - используйте sys. Схема
- представления типа sys.databases
private static bool CheckDatabaseExists(SqlConnection tmpConn, string databaseName)
{
string sqlCreateDBQuery;
bool result = false;
try
{
tmpConn = new SqlConnection("server=(local)\\SQLEXPRESS;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();
object resultObj = sqlCmd.ExecuteScalar();
int databaseID = 0;
if (resultObj != null)
{
int.TryParse(resultObj.ToString(), out databaseID);
}
tmpConn.Close();
result = (databaseID > 0);
}
}
}
catch (Exception ex)
{
result = false;
}
return result;
}
Это будет работать с любым именем базы данных, которое вы передаете в качестве параметра, и вернет логическое значение true = база данных существует, false = база данных не существует (или ошибка получилось).
Разве это
"SELECT * FROM master.dbo.sysdatabases where name = \'INVENTORY\'"
не должно быть этим?
"SELECT * FROM master.dbo.sysdatabases where name = 'INVENTORY'"
Также согласно MSDN
Для операторов UPDATE, INSERT и DELETE возвращаемое значение - количество строк, на которые влияет команда. Когда триггер существует в таблице, которая вставляется или обновляется, возвращаемое значение включает количество строк, затронутых как операцией вставки или обновления, так и количеством строк, затронутых триггером или триггерами. Для всех других типов операторов возвращаемое значение - -1. Если происходит откат, возвращаемое значение также равно -1.
Вы выполняете оператор SELECT, а не DML. Почему бы вам не использовать вместо этого метод ExecuteReader?
Вы не можете использовать ExecuteNonQuery, потому что он всегда будет возвращать -1 для SELECT, как показано в ссылке MSDN.
Вам придется использовать обработку набора результатов, например SELECT DB_ID('INVENTORY') AS DatabaseID
или использовать переменную/параметр: SELECT @DatabaseID = DB_ID('INVENTORY')