Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在创建之前检查数据库是否存在_C#_Sql Server 2005_Tsql - Fatal编程技术网

C# 在创建之前检查数据库是否存在

C# 在创建之前检查数据库是否存在,c#,sql-server-2005,tsql,C#,Sql Server 2005,Tsql,这看起来很琐碎,但现在让我很沮丧 我正在将C与SQLServer2005Express一起使用 我正在使用以下代码。我想在创建数据库之前检查它是否存在。但是,返回的整数是-1,这就是MSDN如何定义ExecuteOnQuery将返回的内容。现在,数据库确实存在,但它仍然返回-1。话虽如此,我如何才能使这项工作达到预期的效果 private static void checkInventoryDatabaseExists(ref SqlConnection tmpConn, ref bool da

这看起来很琐碎,但现在让我很沮丧

我正在将C与SQLServer2005Express一起使用

我正在使用以下代码。我想在创建数据库之前检查它是否存在。但是,返回的整数是-1,这就是MSDN如何定义ExecuteOnQuery将返回的内容。现在,数据库确实存在,但它仍然返回-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) { }

}
这不应该吗

"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方法呢?

您不能使用,因为它将始终为SELECT返回-1,如MSDN链接所示


您必须使用处理结果集,例如选择DB_ID‘INVENTORY’作为数据库ID,或使用变量/参数:SELECT@DatabaseID=DB_ID‘INVENTORY’

从SQL Server 2005开始,旧式的系统对象和系统数据库以及那些目录视图已被弃用。改为这样做-使用sys。模式视图,如sys.databases


这将适用于您作为参数传入的任何数据库名称,它将返回bool true=数据库存在,false=数据库不存在或发生错误。

查询系统视图的另一种方法是使用函数db_id,如果存在,则返回数据库的id,否则为null。下面是T-SQL示例:

if (db_id('INVENTORY') is null)
begin
    return 0
end
else
begin
    return 1
end

读了几年后,有一种更清晰的表达方式:

public static bool CheckDatabaseExists(string connectionString, string databaseName)
{
      using (var connection = new SqlConnection(connectionString))
      {
           using (var command = new SqlCommand($"SELECT db_id('{databaseName}')", connection))
           {
                connection.Open();
                return (command.ExecuteScalar() != DBNull.Value);
           }
      }
}

为了搜索者的利益,如果您使用的是实体框架,则将:

using (var ctx = new MyDataModel())
{
    dbExists = System.Data.Entity.Database.Exists(ctx.Database.Connection);
}

采用Stephen Lloyd的代码并添加了一些异步和sql注入缓解措施

public static async Task<bool> TestDatabase(string connectionString, string databaseName)
{
   using (var connection = new SqlConnection(connectionString))
   using (var command = new SqlCommand("SELECT db_id(@databaseName)", connection))
   {
       command.Parameters.Add(new SqlParameter("databaseName", databaseName));

       connection.Open();

       return (await command.ExecuteScalarAsync() != DBNull.Value);
   }
}
使用此程序集:Microsoft.SqlServer.SqlManagementObjects=>NuGet


我会改用ExecuteReader,因为你现在根本不做DML。。executescalar返回对象,因此您必须在分配前强制转换。它引发列名“INVENTORY”无效的异常抱歉,是的-数据库名称需要用单引号括起来-更新了我的答案这很有效。。如果不存在,则抛出未设置为对象实例的对象引用。否则它将返回一个非零的数据库id!只是想知道为什么不能在这里使用DB_ID?不容易出错,不是吗?看起来是其他人提交的-我很好奇您选择这种方式是否有原因,而不是在这里担心sql注入,使用参数化查询而不是字符串插值,但是db_id是sql Server T-sql函数,所以我看不出sql注入有任何问题。我发现这里使用的连接字符串不能指定要检查的数据库,这似乎是浪费时间。如果存在,则connection.Open将在不存在时引发异常。Open是否具有异步重载?
public static async Task<bool> TestDatabase(string connectionString, string databaseName)
{
   using (var connection = new SqlConnection(connectionString))
   using (var command = new SqlCommand("SELECT db_id(@databaseName)", connection))
   {
       command.Parameters.Add(new SqlParameter("databaseName", databaseName));

       connection.Open();

       return (await command.ExecuteScalarAsync() != DBNull.Value);
   }
}
using Microsoft.SqlServer.Management.Smo;

var dbExists = new Server(serverOrInstanceName).Databases.Contains(dataBaseName);