为什么C#执行SQL语句无法生成SSMS数据库备份?
问题原因分析
UAC虚拟化重定向问题
最常见的原因是备份文件被Windows UAC机制重定向到了虚拟存储路径。SQL Server服务运行账户如果没有目标备份文件夹的显式写入权限,写入操作不会报错,而是会被自动重定向到C:\Users\<SQL Server服务运行账户名>\AppData\Local\VirtualStore\下对应的路径,你可以到该目录下查找生成的备份文件。
注意:BACKUP DATABASE的磁盘写入操作由SQL Server服务的运行账户执行,和你的应用运行账户、数据库连接账户无关,需要给SQL Server对应的服务账户(默认实例是NT SERVICE\MSSQLSERVER,命名实例对应NT SERVICE\MSSQL$实例名)开放备份目标文件夹的读写、修改权限。事务回滚问题
EF框架的ExecuteSqlCommand方法如果运行在隐式事务范围内,备份操作的结果会随事务回滚消失。你可以检查是否有外层事务未提交,也可以修改代码显式控制事务:
public void CreateBackup() { if (!_database.Database.CanConnect()) { throw new Exception("No connection to the Database could be established."); } // 显式开启事务并提交 using var transaction = _database.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted); var backupPath = Path.Combine(_databaseSettings.BackupSettings.BackupFilePath, $"{_databaseSettings.DestinationSettings.SSMSDatabaseName}_{DateTime.Now:dd-MMMM-yyyy HH_mm}.bak"); _database.Database.ExecuteSqlCommand($"BACKUP DATABASE {_databaseSettings.DestinationSettings.SSMSDatabaseName} TO DISK='{backupPath}'"); transaction.Commit(); }
- SQL拼接错误问题
当前用字符串插值拼接SQL的方式存在风险,如果数据库名、路径中存在单引号、特殊符号,实际运行的SQL会和预期不一致。建议改用参数化方式传参,避免拼接导致的静默错误:
var sql = "BACKUP DATABASE @dbName TO DISK = @backupPath"; _database.Database.ExecuteSqlCommand(sql, new SqlParameter("@dbName", _databaseSettings.DestinationSettings.SSMSDatabaseName), new SqlParameter("@backupPath", backupPath));
- 执行状态校验问题
你可以查看ExecuteSqlCommand的返回值,同时检查SQL Server错误日志、Windows事件查看器的应用日志,确认备份操作的实际执行状态,排查静默失败的具体原因。
内容的提问来源于stack exchange,提问作者shinyshark
相关产品推荐
相关产品推荐

