分离本地数据库.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 的第二个参数只是避免更新统计信息(会更快)

您现在可以安全地将 mdfldf 文件从其原始位置移出

假设您的数据库已经离线并且您已将您的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,复制,附加新文件的主要内容,如果未能解决你的问题,请参考以下文章

sql server分离及附加数据库

重装SQLsever2000的数据库会丢失原来的数据吗

sqlserver 分离和附加

将 SQL 数据库文件 MDF 和 LDF 移动到新位置

SQL学习之分离与附加数据库

SQL Server:如何附加/修复分离/损坏的数据库?