MSSQL C#检查数据库存在异常及创建数据库语法错误问题
两个MSSQL数据库操作问题的排查与解决
问题1:检查数据库存在性时ExecuteNonQuery始终返回-1
你这段检查数据库的代码里,问题出在用错了方法,和数据库是否为空完全没关系。
ExecuteNonQuery()的设计初衷是执行INSERT/UPDATE/DELETE这类修改数据的语句,返回受影响的行数。但你执行的是SELECT查询,对于这类不修改数据的语句,ExecuteNonQuery()固定返回-1——不管结果集里有没有数据,这就是你明明数据库存在,却一直拿到-1的原因。
修正方案
要判断数据库是否存在,用ExecuteScalar()(返回结果集第一行第一列)最简洁,同时还能顺便修复原代码的SQL注入风险:
private bool CheckDatabase(string databaseName) { string connString = "Server=localhost\\SQLEXPRESS;Integrated Security=SSPI;database=master"; string cmdText = "SELECT 1 FROM master.dbo.sysdatabases WHERE name = @DatabaseName"; using (SqlConnection sqlConnection = new SqlConnection(connString)) { sqlConnection.Open(); using (SqlCommand sqlCmd = new SqlCommand(cmdText, sqlConnection)) { sqlCmd.Parameters.Add("@DatabaseName", System.Data.SqlDbType.NVarChar).Value = databaseName; // 查到数据返回1,否则返回null object result = sqlCmd.ExecuteScalar(); return result != null; } } }
问题2:创建数据库时参数化语句报语法错误
这个问题的核心是:SQL Server不允许用参数指定数据库名(或表名、列名这类对象名称)。参数只能传递值(比如WHERE子句的条件值),不能替换对象标识符,所以CREATE DATABASE @userDatabase会直接触发语法错误。
解决方法
要动态指定数据库名,需要用动态SQL,但一定要做好注入防护。最稳妥的方式是用QUOTENAME()函数转义数据库名,自动处理特殊字符和关键字:
var connString = "Server=localhost\\SQLEXPRESS;Integrated Security = SSPI; database = master"; // 用QUOTENAME确保数据库名的安全性 string cmdText = "CREATE DATABASE " + QUOTENAME(@userDatabase); using (var sqlConnection = new SqlConnection(connString)) { using (var sqlCmd = new SqlCommand(cmdText, sqlConnection)) { sqlCmd.Parameters.Add("@userDatabase", System.Data.SqlDbType.NVarChar).Value = databaseName; sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); } }
如果不想用动态SQL,也可以直接拼接字符串,但必须严格验证databaseName的格式(比如只允许字母、数字和下划线),不过QUOTENAME()是更安全的选择。
内容的提问来源于stack exchange,提问作者positive perspective
相关产品推荐
相关产品推荐

