ASP.NET 執行備份/還原本質上是透過 ADO.NET 送出 T-SQL 指令(BACKUP/RESTORE DATABASE),差別僅在於權限需求與語法細節。
BACKUP DATABASE @dbName TO DISK = @bakName
@dbName:欲備份的資料庫名稱。@bakName:備份檔完整路徑(.bak),需 SQL Server 服務帳號具寫入權限。db_owner 角色成員,或具備 BACKUP DATABASE 權限。還原需強制離線資料庫以終止現有連線,步驟如下:
-- 1. 強制離線(終止所有連線)
ALTER DATABASE {0} SET OFFLINE WITH ROLLBACK IMMEDIATE;
-- 2. 還原資料庫
RESTORE DATABASE @dbName FROM DISK = @bakName;
-- 3. 上線資料庫
ALTER DATABASE {0} SET ONLINE WITH ROLLBACK IMMEDIATE;
{0}:資料庫名稱,因 RESTORE 不支援變數直接代入資料庫名稱,需在 C# 中使用 string.Format 組合完整 SQL 字串。@dbName、@bakName:同備份語法。db_owner 外,尚需 sysadmin 或 dbcreator 固定伺服器角色,且操作時連線至 master 資料庫。public void BackupDatabase(string dbName, string bakPath)
{
using (var conn = new SqlConnection("Server=.;Database=master;Integrated Security=true;"))
{
conn.Open();
string sql = $"BACKUP DATABASE [{dbName}] TO DISK = '{bakPath}' WITH INIT, STATS=10";
using (var cmd = new SqlCommand(sql, conn))
{
cmd.CommandTimeout = 300;
cmd.ExecuteNonQuery();
}
}
}
public void RestoreDatabase(string dbName, string bakPath)
{
using (var conn = new SqlConnection("Server=.;Database=master;Integrated Security=true;"))
{
conn.Open();
// 1. 離線
string offlineSql = $"ALTER DATABASE [{dbName}] SET OFFLINE WITH ROLLBACK IMMEDIATE";
using (var cmd = new SqlCommand(offlineSql, conn)) { cmd.ExecuteNonQuery(); }
// 2. 還原
string restoreSql = $"RESTORE DATABASE [{dbName}] FROM DISK = '{bakPath}' WITH REPLACE, STATS=10";
using (var cmd = new SqlCommand(restoreSql, conn))
{
cmd.CommandTimeout = 600;
cmd.ExecuteNonQuery();
}
// 3. 上線
string onlineSql = $"ALTER DATABASE [{dbName}] SET ONLINE";
using (var cmd = new SqlCommand(onlineSql, conn)) { cmd.ExecuteNonQuery(); }
}
}
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 備份/還原失敗,提示「存取被拒」 | SQL Server 服務帳號無磁碟路徑讀寫權限 | 授予服務帳號資料夾完整控制權限,或使用網路共享路徑並設定權限 |
| 還原時卡住、報錯「資料庫正在使用中」 | 未成功離線或有殘留連線 | 確認 ALTER DATABASE OFFLINE 成功;必要時重啟 SQL Server 服務 |
| 還原後資料庫進入「Restoring」狀態 | 缺少 WITH RECOVERY 或檔案損壞 | 加上 WITH RECOVERY(預設);檢查備份檔完整性 |
DB_20240115_0300.bak),利於版本管理。RESTORE VERIFYONLY)。