使用C#实现SQL Server备份时参数未提供错误的解决方法
SQL Server数据库备份应用参数错误问题
我开发了一个用于备份SQL Server数据库的控制台应用,使用的代码如下:
static void CreateBackup(string connectionString, string databaseName, string backupFilePath) { backupFilePath = backupFilePath + "\\" + databaseName + ".bak"; backupFilePath = @"" + backupFilePath; var backupCommand = "BACKUP DATABASE @databaseName TO DISK = @backupFilePath"; using (var conn = new SqlConnection(connectionString)) using (var cmd = new SqlCommand(backupCommand, conn)) { conn.Open(); cmd.Parameters.AddWithValue("@databaseName", databaseName); cmd.Parameters.AddWithValue("@backupFilePath", backupFilePath); cmd.ExecuteNonQuery(); } }
启动应用时,始终收到如下错误:
System.Data.SqlClient.SqlException (0x80131904): The parameterized query '(@databaseName nvarchar(4000),@backupFilePath nvarchar(5))BACKUP' expects the parameter '@databaseName', which was not supplied.
问题原因及解决方法
核心原因
SQL Server不允许把数据库名称作为参数化查询的参数来用,BACKUP DATABASE里的数据库名属于对象标识符,不属于普通数据值,没法通过@databaseName这种参数形式传递,这就是报错的根本原因。
修复步骤
将数据库名直接拼入SQL语句:
数据库名是SQL语法的一部分,必须直接写进语句里。如果databaseName是你自己可控的(不是用户输入的内容),直接拼接就安全;如果是用户输入的,一定要用SqlCommandBuilder.QuoteIdentifier方法转义,防止SQL注入。清理冗余代码:
原代码里backupFilePath = @"" + backupFilePath;完全没用,直接删掉就行。
修复后的代码
static void CreateBackup(string connectionString, string databaseName, string backupFilePath) { // 用Path.Combine简化路径拼接,避免手动处理斜杠问题 string backupFullPath = Path.Combine(backupFilePath, $"{databaseName}.bak"); using (var conn = new SqlConnection(connectionString)) { conn.Open(); // 转义数据库名,处理特殊字符和注入风险 string quotedDbName = conn.CreateCommand().QuoteIdentifier(databaseName); string backupCommand = $"BACKUP DATABASE {quotedDbName} TO DISK = @backupFilePath"; using (var cmd = new SqlCommand(backupCommand, conn)) { // 备份路径属于数据值,可以安全参数化 cmd.Parameters.AddWithValue("@backupFilePath", backupFullPath); cmd.ExecuteNonQuery(); } } }
补充说明
- 只有普通数据值(比如查询条件、插入的内容)才能用参数化,对象名称(数据库、表、列名)属于SQL结构的一部分,只能直接写入语句。
QuoteIdentifier会自动处理数据库名里的空格、保留字等特殊情况,同时杜绝SQL注入的可能。
内容的提问来源于stack exchange,提问作者ogiyavuz
相关产品推荐
相关产品推荐

