SQL Server LocalDB:将数据库分离并重新附加到同一台计算机(机器,相同路径)后,无法备份数据库

Posted

技术标签:

【中文标题】SQL Server LocalDB:将数据库分离并重新附加到同一台计算机(机器,相同路径)后,无法备份数据库【英文标题】:SQL Server LocalDB: after detach and re-attach database to same computer(machine, same path), cannot backup database 【发布时间】:2016-04-24 07:44:07 【问题描述】:

我的开发环境是 C#、SQL Server 2014 LocalDB、SQL Server 2012 Express、Windows 10、Visual Studio 2015。

当我的应用程序的用户需要将他们的 localDB (.mdf) 文件移动到另一个地方,另一台计算机(LocalDB 服务器),从计算机 A 分离并附加到计算机 B,然后我们可以成功运行 BACKUP 数据库命令。

但是,如果用户错误地分离或用户改变主意继续在计算机 A 中使用,我的应用程序必须能够将分离的 LocalDB 数据库文件 (.mdf) 重新附加到同一台计算机(相同的 LocalDB 服务器)。

当我的应用程序成功将数据库文件重新附加到同一台计算机后运行BACKUP DATABASE 命令时,错误消息显示为,

无法打开物理文件,进程无法访问 dbfile,因为 dbfile 正在被另一个进程使用

备份数据库异常终止

所以,我进入 Microsoft Server Management Studio,可以看到 2 个具有特定名称的 dbfile,第一个是 greendb.mdf(唯一名称),第二个是 c:\users\kay\appdata\greendb.mdf(带有完整路径)。

我认为c:\users\kay\appdata\greendb.mdf(带有完整路径)是在分离数据库时创建的。当我通过 security-login-kay-user 映射单击它时,与其他数据库在内部显示其权限不同,具有完整路径的分离数据库不会显示其权限并显示错误消息,例如,

无法将“System.DBNull”对象转换为“System.String”(Microsoft.SqlServer.Smo)

Microsoft LocalDB Server 似乎仍然可以识别具有完整路径的分离数据库,并与新附加的数据库混淆(只有名称没有完整路径)。

任何优秀的想法都将受到高度赞赏!

非常感谢!

【问题讨论】:

今天,我发现如果我分离localdb并在WPF的同一个窗口(用于登录)中连续附加,则在下一个窗口(我的应用程序的主窗口)中备份数据库成功完毕。但是,我假设如果我在分离 localdb 数据库后关闭窗口或关闭(退出)应用程序,似乎 localdb 服务器创建具有完整路径名的幽灵(不是官方的)localdb 来使用幽灵(不是官方的)做一些分配的额外工作) localdb 文件,因为服务器上没有正式的 localdb 文件。 我现在已经测试并确认 100% 如果我在 WPF 的同一窗口中连续分离和附加,幽灵 localdb 没有创建,我可以看到备份数据库命令已成功完成。我们是否需要做一些额外的工作来彻底清除 localdb Sever 上的名称? detach 和 Create database For Attach 命令中是否需要一些必要的选项(参数)? 【参考方案1】:

在分离localDB时,

我们必须先运行 ALTER DATABASE ROLLBACK IMMEDIATE 命令来终止所有未完成的事务。

简单解释一下,在我们关闭一家餐厅之前,我们必须向餐厅内的顾客宣布,'这家餐厅即将关闭,请在餐厅关闭前完成您的用餐并外出'

如果您需要将 localDB 重新连接到同一台计算机(同一 localDB 服务器),

为了防止出现幽灵(错误?),必须避免此类活动。

1) 尝试以代码方式打开localDB

2) 似乎用分离的localDB的名字来计数也提醒localDB服务器的存在。(master数据库中的SELECT COUNT dbname命令)

奇怪的是,必须将其修复为错误,

如果我们从主数据库中分离一个 localDB,我认为它必须无法以编程方式在代码中打开分离的 localDB。但是,像 SqlConnection.Open(); 这样的代码运行并通过,没有任何异常(错误),并立即创建全路径幽灵。

似乎主数据库上已删除分离的localDB的名称,但服务器通过提供的连接字符串中的物理路径连接分离的localDB。

为了决定是否需要附加一些 localDB 或检查它是否分离,我已经开发了自己的解决方案(简单代码)来执行此操作。

希望我的经验对其他人有所帮助。

【讨论】:

【参考方案2】:

嗯,我使用附加和分离操作做了很多工作,最后我发现作为开发人员的最佳实践是使用脚本。

因此,如果您想(分离)您的数据库以使用新名称或相同名称再次重新(附加)。我建议您为您的数据库生成脚本并再次编写脚本。

如果你直接运行脚本你会得到一个错误,因为你必须删除旧数据(旧/新具有相同的名称)并且脚本默认使用写在第一行的数据库名称,当然您可以删除此行并使用您要使用的新数据库。

对于包含数据的脚本数据库,请确保从向导中设置首选项(高级设置 => 仅架构/仅数据/架构和数据。)选择架构和数据

默认情况下,选择仅是架构。 在运行脚本并删除旧数据后,为您的 sql 文件选择一个目标。您的备份过程应该没有问题。

【讨论】:

哦..非常感谢您的回答。我正在尝试使用您的感谢关键字查找,但暂时很难找到。我不能使用向导,但必须从用户端以编程方式进行。如何删除旧数据和包括数据库名称的第一行?以及如何将首选项设置为 Schema 和 Data ?互联网上似乎没有这方面的信息。您能否通过一些简单的代码示例分享您的宝贵经验和知识?近 1 个月以来,我一直在努力解决这个问题。非常感谢!

以上是关于SQL Server LocalDB:将数据库分离并重新附加到同一台计算机(机器,相同路径)后,无法备份数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SQL Server LocalDB 数据库移动到新计算机

009.Working with SQL Server LocalDB --在sql server localdb 上操作数据

无法将 SQL Server LocalDB 用于我的 WPF 应用程序

将 SQL Server 身份验证与 localdb 一起使用

SQL Server 2012 Express LocalDB

为 SQL Server LocalDB 创建永久别名