LocalDB v14はmdfファイルの間違ったパスを作成します


34

最近、SQL Server Expressインストーラーとこの手順を使用して、LocalDBをバージョン13から14にアップグレードしました。インストール後、バージョン13の既存のデフォルトインスタンス(MSSQLLOCALDB)を停止し、v14.0.1000サーバーエンジンを自動的に使用する新しいインスタンスを作成しました。

データベース統合テストによくLocalDBを使用します。つまり、xunitテストでは、テストが終了すると削除される(一時的な)データベースを作成します。新しいバージョン以降、残念ながら次のエラーメッセージが原因ですべてのテストが失敗します。

物理ファイル 'C:\ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf'を開くまたは作成しようとしたときに、CREATE FILEでオペレーティングシステムエラー5(アクセスが拒否されました)が発生しました。

奇妙なことは、mdfファイルのターゲットパスが正しくないことです。C:\ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf(単一のテストのランダムなデータベース名)の間にバックスラッシュがありません。データベースは単純なコマンドで作成されますCREATE DATABASE [databaseName]-ここでは特別なことは何もありません。

SSMSでは、データ、ログ、およびバックアップのターゲットの場所は次のとおりです。

LocalDBターゲットの場所

ただし、場所を更新しようとすると、別のエラーメッセージが表示されます。

更新しようとしたときのエラーメッセージ

LocalDBがデータベースを再度作成できるように、デフォルトの場所を更新するにはどうすればよいですか?LocalDBがデフォルトのロケーションディレクトリとデータベースファイル名を正しく結合していないことは明らかです。編集できるレジストリエントリはありますか?または他に何か?

Dougの回答とsepupicのコメントの後の更新

このStackoverflowの質問によると、デフォルトの場所もレジストリ経由で変更可能である必要があります。ただし、対応するキー「DefaultData」、「DefaultLog」、および「BackupDirectory」を見つけようとすると、レジストリでそれらを見つけることができません。SQL Server v14はこれらのレジストリキーの名前を変更しましたか、またはこれらの情報をレジストリから移動しましたか?


参考までに、SSMSを管理モードで実行している場合、データベースのデフォルトの場所を更新することもできません。
feO2x

1
私の答えの更新をご覧ください。このバグは... 4月中旬にリリース、CU6のよう修正されました
ソロモンRutzky

回答:


21

更新

SQL Server 2017のCU 6の時点で、このバグは修正されました。以下を正常に実行できるようになりました。

CREATE DATABASE [CreateDatabaseTest];
DROP DATABASE [CreateDatabaseTest];

この問題、およびCU6で修正されているという事実は、次のKB記事に記載されています。FIX
:SQL Server 2017 Express LocalDBでデータベースを作成しようとすると、「アクセスが拒否されました」エラー

累積更新プログラムを入手するには、次のページに移動して、トップ(つまり、最新の)ビルドを取得してください。

SQL Server 2017ビルドバージョン


SQL Server 2017 CU6の時点で廃止された情報(2018年4月17日リリース)

結合されたパスとファイル名にバックスラッシュがないことは、SQL Server 2017のバグのようです。レジストリを編集して、次のキーの両方にC:\ Users \ MyAccountName \のDefaultData文字列値を追加することも試みました(3つのデフォルトパスは、調べたLocalDBレジストリキーのいずれにもありません)。

  • Computer \ HKEY_CURRENT_USER \ Software \ Microsoft \ Microsoft SQL Server \ UserInstances \ {some-GUID-value}
  • Computer \ 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

回避策と同様に、データベース設定でLocalDb接続の場合はMDFファイルのパスを指定するというアプローチを取っています。ただし、LDFまたはステートメントのLOG ONセクションの名前も指定する必要はないようですCREATE DATABASE。LDFファイルは、デフォルトでは、MDFファイルと同じ場所に作成されるようです。(LocalDbの使用例は、主に自動テストで使用されます。)
tgharold

@tgharold私の答えの上部にある更新をご覧ください。このバグはごく最近、新しいCU6パッチで修正されました:-)。
ソロモンラツキー

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)

動的SQLを使用しており、正確ではありませんが、問題に対する公式の修正が行われるまで仕事は完了します。


1
面白い。それは可能性がある第二を移動するためにわずかに良いことQUOTENAMEの第二のparamにFORMATMESSAGEファイルパスを二重引用符を置きます:FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);。しかし、現在のように機能するようですので、このアプローチに+1してください。USERPROFILEルートを使用したくない場合は、名前をハードコーディングするかパスを渡すかのいずれかの場合があります。しかし、ここでそれを許可し、デフォルトでInstanceDefaultDataPathifにすることができます@Path IS NULL。:-)
ソロモンラツキー

ありがとうございました。あなたの提案で答えを編集しました。絶対パスをハードコーディングすることは、依然として有効な解決策であることは間違いありません。ただし、このシナリオでは、自動テスト中にデータベースを再作成するだけであり、ローカルマシン上のまったく同じパスにフォルダーを作成する全員を調整することなく、すべての同僚とビルドサーバーで動作することを確認する必要がありました。:-)
ニコライダムラーセン

4

私もこの問題に直面しています。私が見つけた唯一の回避策はc:\Users\、Everyone(またはそのようなもの)への書き込みアクセスを許可し、必要な場所にmdfファイルを作成できるようにすることです。


1
おかげで、これも私にとっては解決しました!この回避策はひどいですが、それはローカルビルドサーバー上にあるだけなので、追加のユーザー権利については気にしません。
ハンネスザクセン

@HannesSachsenhofer:同意します、それは最悪です。しかし、私はLocalDB開発チームから次のホットフィックスリリースでこのバグを修正すると約束されました。
アバティシュチェフ

すべての人に書き込みアクセスを許可することは、私にとってはかなり悪い回避策のようです
ラファエル

@ラファエロ:なぜですか?開発ボックスに複数のユーザーがいますか?そして、あなたは誰を信頼していませんか?
アバティシュチェフ

2

この問題について簡潔に説明していただきありがとうございます。昨日、この同じ問題に遭遇しました。私はまだ永続的な解決策を見つけていませんが、ここに私の現在の回避策があります。

Database.EnsureCreated()関数を使用してデータベースを作成しています。

接続文字列を設定して、「AttachDBFilename =」設定を含めます。

Server=(LocalDB)\\MSSQLLocalDB;Database=ExploreCalifornia;AttachDbFilename=.\\ExploreCalifornia.mdf;Trusted_Connection=True;MultipleActiveResultSets=true

アプリケーションを実行します。エラーが生成されます:

ファイル「。\ ExploreCalifornia.mdf」をデータベース「ExploreCalifornia」として添付できません。

しかし、データベースを作成します。

その後、接続文字列を変更し、「AttachDBFilename =」を削除します。

 Server=(localdb)\\MSSQLLocalDB;Database=ExploreCalifornia;Trusted_Connection=True;MultipleActiveResultSets=true

エラーなしでアプリケーションを再度実行し、テーブルが作成されました。


いくつかの質問:まず、念のため-最初に(アクセスが拒否されました)エラーが表示されていましたが、これで解決しましたか?第二に、SQL Server Management StudioはIPが言及している唯一のアプリケーションであり、これはあなたがそこからやったことのようには思えません。
RDFozz

あなたの答えをありがとう、しかしこれは本当に私の問題を解決しません。私のテストコードはCREATE DATABASE [databasename]LocalDBに対して単純な新しいデータベースを作成し、LocalDBがランダムに生成されたデータベース名とデフォルトの場所ディレクトリを誤って連結するため、このまさにステートメントが問題を引き起こしています(私の質問の段落3および4を参照)。この連結の問題が発生しないように、デフォルトの場所を修正する方法が必要です。
feO2x

現在、SQL / DDLを介してデータベースを作成することはまったくできません。LocalDBは常にUsersディレクトリにデータベースを直接作成しようとするため、SSMS経由で、またはコードから、または他の場所からステートメントを実行するかどうかは関係ありません(これは完全に間違っています、このディレクトリにファイルは存在できません) 。
feO2x

1
あなたはおそらくスペルミスをしましたAttachDBFilename
tgharold
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.