Проверьте, существует ли База данных Перед Созданием

Это кажется довольно тривиальным, но это теперь расстраивает меня.

Я использую 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) { }

}
33
задан 5 July 2011 в 12:25
поделиться

3 ответа

Начиная с 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 = база данных не существует (или ошибка получилось).

54
ответ дан 27 November 2019 в 17:35
поделиться

Разве это

"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?

7
ответ дан 27 November 2019 в 17:35
поделиться

Вы не можете использовать ExecuteNonQuery, потому что он всегда будет возвращать -1 для SELECT, как показано в ссылке MSDN.

Вам придется использовать обработку набора результатов, например SELECT DB_ID('INVENTORY') AS DatabaseID или использовать переменную/параметр: SELECT @DatabaseID = DB_ID('INVENTORY')

3
ответ дан 27 November 2019 в 17:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: