应优先使用smo库执行sql server备份,设database、devices.adddevice()路径、initialize=true、async=false;失败时捕获msg 3201/3013/913并校验权限、连接、实例;备份后必执行restore verifyonly。

SQL Server 备份命令在 C# 中怎么安全执行
直接调用 sqlcmd 或拼接 BACKUP DATABASE 语句是常见做法,但容易因权限、路径、连接状态出错。关键不是“能不能跑”,而是“失败时有没有明确提示”。
- 优先用 SQL Server 的
SMO库(Microsoft.SqlServer.Smo),它封装了备份逻辑,自动处理设备类型、超时、日志截断等细节 - 确保运行 C# 程序的账户对目标备份路径有写权限——本地路径如
C:\Backup\在 IIS 或 Windows Service 下常被拒绝,建议改用 UNC 路径或 SQL Server 服务账户有权限的本地目录 - 不要用字符串拼接数据库名,必须校验
databaseName是否为合法标识符,否则可能触发 SQL 注入或语法错误;可用Microsoft.Data.SqlClient.Server.DbConnection.GetSchema("Databases")先查是否存在 - 执行前检查数据库状态:
SELECT state_desc FROM sys.databases WHERE name = 'xxx',避免对RESTORING或OFFLINE数据库发起备份
SMO 备份代码里哪些参数不能省
SMO 的 Backup 对象看着简单,但漏掉几个关键属性会导致备份无效或不可还原。
-
Database属性必须设为待备份的数据库名(字符串),不能留空或传错大小写(区分大小写取决于实例排序规则) -
Devices.AddDevice()必须指定完整物理路径,且后缀要匹配设备类型:文件备份用DeviceType.File,路径如C:\Backup\mydb_full_20240512.bak -
Initialize = true表示覆盖同名文件,不设的话连续备份会追加到同一文件,恢复时需指定FILE = n,极易出错 - 务必设置
Async = false(默认是false,但显式写上更安全),否则SqlException可能被吞掉,程序以为成功了其实没写完
备份失败时最常见的三个 SqlException 错误码
不是所有报错都该重试,得看错误来源。以下三个最常出现,对应不同修复动作:
-
Msg 3201, Level 16:无法打开备份设备——检查路径是否存在、磁盘是否满、SQL Server 服务账户是否有写权限(不是当前登录用户) -
Msg 3013, Level 16:备份过程被中断——常因网络断开(远程备份)、杀进程、或未设Timeout导致连接超时;建议在SqlConnection连接字符串中加Connection Timeout=600 -
Msg 913, Level 16:找不到数据库——注意不是数据库名输错,而是当前连接的实例里根本没这个库,比如连错了命名实例,或数据库刚被 detach
备份文件生成后要不要校验有效性
只看文件大小不为 0 是远远不够的。SQL Server 不会在备份中途写入有效头信息,所以一个 1KB 的 .bak 文件也可能是失败产物。
- 立即执行
RESTORE VERIFYONLY FROM DISK = 'C:\Backup\...\bak'是最轻量的校验方式,耗时短且不占用额外空间 - 若用 SMO,可调用
Restore.SqlVerify(server),它内部就是发VERIFYONLY命令 - 生产环境建议把校验结果写入日志,哪怕只是记录
VerifyResult == true,否则几个月后发现备份全失效,已经没法补救
实际部署时最容易被忽略的是:备份路径的权限归属和 VERIFYONLY 的执行时机。很多团队只验证首次备份,后续就跳过——但磁盘故障、防病毒软件拦截、NTFS 配额限制都可能让某次备份静默损坏。










