分离本地数据库.mdf,复制,附加新文件
Posted
技术标签:
【中文标题】分离本地数据库.mdf,复制,附加新文件【英文标题】:Detach local database .mdf, copy, attach the new file 【发布时间】:2016-12-18 04:21:18 【问题描述】:我尝试分离我的本地数据库 .mdf 将其复制到另一个文件夹并在启动时附加新文件并在关闭时复制到旧文件夹。
它似乎在启动时有效,但在表单关闭时出现错误:
该进程无法访问文件“C:\ProgramData\MyData\db1.mdf”,因为它正被另一个进程使用。
这是我的代码:
public Form()
InitializeComponent();
DetachDatabase();
CopyDb();
AttachDatabase();
AppDomain.CurrentDomain.SetData("DataDirectory", Data.MyNewFolder);
public static bool DetachDatabase()
try
string connectionString = String.Format(@"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True");
using (var cn = new SqlConnection(connectionString))
cn.Open();
SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = String.Format("exec sp_detach_db '0'", "db1");
cmd.ExecuteNonQuery();
cmd.CommandText = String.Format("exec sp_detach_db '0'", "db2");
cmd.ExecuteNonQuery();
return true;
catch
return false;
public static bool AttachDatabase()
try
string connectionString = String.Format(@"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True");
using (var cn = new SqlConnection(connectionString))
cn.Open();
SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = String.Format("exec sys.sp_attach_db db1, 'db1.mdf'");
cmd.CommandText = String.Format("exec sys.sp_attach_db db2, 'db2.mdf'");
cmd.ExecuteNonQuery();
return true;
catch
return false;
private void Frm_FormClosing(object sender, FormClosingEventArgs e)
LocalDB.DetachDatabase();
CopyDb();
LocalDB.AttachDatabase();
有什么好的方法吗?
谢谢
【问题讨论】:
SQL Server 是一个基于服务器的数据库系统——所以最好的方法是NOT 摆弄.mdf
文件,然后将数据库留在服务器上 并连接到它并使用它
【参考方案1】:
需要切换到master
,将目标数据库下线
警告:使用风险自负(例如,您可以使用WITH ROLLBACK IMMEDIATE
吗?)
var commandText = string.Format(@"
USE MASTER;
ALTER DATABASE 0 SET OFFLINE WITH ROLLBACK IMMEDIATE;
EXEC sp_detach_db '0', 'true';", "db1");
sp_detach_db
的第二个参数只是避免更新统计信息(会更快)
您现在可以安全地将 mdf
和 ldf
文件从其原始位置移出
假设您的数据库已经离线并且您已将您的db1.mdf
文件移动到D:\Whatever
,我认为您可以这样做(我没有测试它,当心)
var commandText = string.Format(@"
USE MASTER;
ALTER DATABASE 0
MODIFY FILE (
NAME = '0',
FILENAME = 'D:\Wherever\0.mdf');
ALTER DATABASE 0 SET ONLINE;", "db1");
【讨论】:
对于关闭数据库仍然附加但我发现这样做 var start = new ProcessStartInfo("sqllocaldb", "stop MSSQLLocalDB"); start.WindowStyle = ProcessWindowStyle.Hidden;使用 (var stop = Process.Start(start)) stop.WaitForExit(); start.Arguments = "删除 MSSQLLocalDB";使用 (var delete = Process.Start(start)) delete.WaitForExit(); 我想知道是否没有办法在调用返回之前强制数据库完全分离(例如设置单用户模式,重新连接后返回多用户)。重新启动该过程感觉不正确,但是,好吧...:D Aslo,如果这是您的主要形式,为什么不在形式完全销毁(以及在构造之前)分离/附加而不是使用事件处理程序?以上是关于分离本地数据库.mdf,复制,附加新文件的主要内容,如果未能解决你的问题,请参考以下文章