LocalDB v14 为 mdf 文件创建错误的路径

feO*_*O2x 40 sql-server sql-server-localdb

最近,我使用 SQL Server Express 安装程序和此说明将 LocalDB 从版本 13 升级到 14 。安装后,我停止了现有的13版默认实例(MSSQLLOCALDB)并创建了一个新实例,该实例自动使用了v14.0.1000服务器引擎。

我经常使用 LocalDB 进行数据库集成测试,即在我的 xunit 测试中,我创建了一个(临时)数据库,该数据库在测试完成时被删除。由于新版本,不幸的是,由于以下错误消息,我所有的测试都失败了:

CREATE FILE 在尝试打开或创建物理文件“C:\Users\kepflDBd0811493e18b46febf980ffb8029482a.mdf”时遇到操作系统错误 5(访问被拒绝。)

奇怪的是,mdf 文件的目标路径不正确,在C:\Users\kepflDBd0811493e18b46febf980ffb8029482a.mdf(这是单个测试的随机数据库名称)之间缺少反斜杠。数据库是通过简单的命令创建的CREATE DATABASE [databaseName]——这里没有什么特别的。

在 SSMS 中,我看到数据、日志和备份的目标位置如下:

LocalDB 目标位置

但是,当我尝试更新位置时,我收到另一条错误消息:

尝试更新时出现错误消息

如何更新默认位置以便 LocalDB 能够再次创建数据库?很明显,LocalDB 没有正确组合默认位置目录和数据库文件名 - 是否有我可以编辑的注册表项?或者别的什么?

在 Doug 的回答和 sepupic 的评论后更新

根据这个 Stackoverflow question,默认位置也应该可以通过注册表更改。但是,如果我尝试查找相应的键“DefaultData”、“DefaultLog”和“BackupDirectory”,则无法在我的注册表中找到它们。SQL Server v14 是否重命名了这些注册表项,或将这些信息移出了注册表?

Sol*_*zky 30

更新

从 SQL Server 2017 的 CU 6 开始,此错误已得到修复。现在可以成功执行以下操作:

CREATE DATABASE [CreateDatabaseTest];
DROP DATABASE [CreateDatabaseTest];
Run Code Online (Sandbox Code Playgroud)

该问题及其在 CU6 中已修复的事实记录在以下知识库文章中:
修复:尝试在 SQL Server 2017 Express LocalDB 中创建数据库时出现“访问被拒绝”错误

要获得累积更新,请转到以下页面并获取顶级(即最新)版本,这可能比 CU6 更新,具体取决于您何时看到:

SQL Server 2017 内部版本


以下信息已过时 SQL SERVER 2017 CU6(发布于 2018-04-17)

组合路径 + 文件名中缺少反斜杠似乎是 SQL Server 2017 的一个错误。我自己也遇到了。我什至尝试编辑注册表以在以下两个键中DefaultDataC:\Users\MyAccountName\添加字符串值(3 个默认路径不在我查看的任何 LocalDB 注册表项中):

  • 计算机\HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server\UserInstances\{some-GUID-value}
  • 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14E.LOCALDB\MSSQLServer

是的,我在两次尝试中都关闭并重新启动了 LocalDB 实例。

但是,我不相信无法更改默认路径是一个错误,因为它可能只是糟糕的文档和糟糕的错误处理相结合。我这样说是因为我刚刚尝试编辑 SQL Server LocalDB 版本 2014、2016 和 2017 的默认位置,所有结果都导致完全相同的错误,这本身很奇怪,因为来自RegCreateKeyEx(),它应该处理注册表和不是文件系统。

由于在创建新数据库时没有指定要使用的文件时缺少反斜杠,因此无法更改路径是不幸的。但是,我能够使用完整的CREATE DATABASE语法创建一个新的数据库,如下所示:

CREATE DATABASE [XXXXX]
 CONTAINMENT = NONE
 ON PRIMARY 
( NAME = N'XXXXX_sys', FILENAME = N'C:\Users\MyAccountName\XXXXX_sys.mdf',
  SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB ), 
 FILEGROUP [Tables] DEFAULT
( NAME = N'XXXXX_data', FILENAME = N'C:\Users\MyAccountName\XXXXX_data.ndf',
  SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'XXXXX_log', FILENAME = N'C:\Users\MyAccountName\XXXXX_log.ldf',
  SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 COLLATE Latin1_General_100_CS_AS_KS_WS_SC;
GO
Run Code Online (Sandbox Code Playgroud)


Nik*_*sen 5

我遇到了同样的问题,并找到了一个不应该有任何明显缺点的解决方法(如果我忘记了什么,请纠正我)。它基于 Solomons 的答案,但无需直接指定数据库文件的绝对路径。

DECLARE @databaseName NVARCHAR(MAX) = 'MyDatabase'

DECLARE @dataFilePath NVARCHAR(MAX) = CAST(SERVERPROPERTY('InstanceDefaultDataPath') AS NVARCHAR) 
    + FORMATMESSAGE('\%s.mdf', @databaseName)

DECLARE @sql NVARCHAR(MAX) = FORMATMESSAGE(
    'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = ''%s'' )', 
    quotename(@databaseName), quotename(@databaseName), @dataFilePath
)

EXEC (@sql)
Run Code Online (Sandbox Code Playgroud)

它使用动态 sql 并且不是很漂亮,但它可以完成工作,直到问题得到正式修复。