LocalDB v14 membuat jalur yang salah untuk file mdf


34

Baru-baru ini, saya memutakhirkan LocalDB dari versi 13 ke 14 menggunakan penginstal SQL Server Express dan instruksi ini . Setelah instalasi, saya menghentikan instance default yang ada (MSSQLLOCALDB) versi 13 dan membuat yang baru, yang secara otomatis menggunakan mesin server v14.0.1000.

Saya sering menggunakan LocalDB untuk tes Integrasi Basis Data, yaitu dalam tes xunit saya, saya membuat database (sementara) yang dihapus ketika tes selesai. Sejak versi baru, sayangnya semua pengujian saya gagal karena pesan kesalahan berikut:

BUAT FILE menemukan kesalahan sistem operasi 5 (Akses ditolak.) Saat mencoba membuka atau membuat file fisik 'C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf'

Yang aneh adalah bahwa path target untuk file mdf tidak benar, backslash hilang antara C: \ Users \ kepfl dan DBd0811493e18b46febf980ffb8029482a.mdf (yang merupakan nama database acak untuk satu tes). Basis data dibuat melalui perintah sederhana CREATE DATABASE [databaseName]- tidak ada yang istimewa di sini.

Di SSMS, saya melihat bahwa lokasi target untuk data, log, dan cadangan adalah sebagai berikut:

Lokasi target LocalDB

Namun, ketika saya mencoba memperbarui lokasi, saya mendapatkan pesan kesalahan lain:

Pesan kesalahan saat mencoba memperbarui

Bagaimana saya bisa memperbarui lokasi default sehingga LocalDB dapat membuat database lagi? Sudah jelas bahwa LocalDB tidak menggabungkan direktori lokasi default dan nama file database dengan benar - apakah ada entri registri yang dapat saya edit? Atau sesuatu yang lain?

Update setelah jawaban Doug dan komentar sepupic

Menurut pertanyaan Stackoverflow ini , lokasi default juga harus dapat diubah melalui registri. Namun, jika saya mencoba menemukan kunci yang sesuai "DefaultData", "DefaultLog" dan "BackupDirectory", saya tidak dapat menemukannya di registri saya. Apakah SQL Server v14 mengubah nama kunci registri ini, atau memindahkan informasi ini dari registri?


FYI, saya juga tidak dapat memperbarui lokasi default Database ketika menjalankan SSMS dalam mode admin.
feO2x

1
Silakan lihat pembaruan dalam jawaban saya. Bug ini telah diperbaiki pada CU6, dirilis pada pertengahan April ..
Solomon Rutzky

Jawaban:


21

MEMPERBARUI

Pada CU 6 untuk SQL Server 2017, bug ini telah diperbaiki. Sekarang dimungkinkan untuk menjalankan yang berikut ini dengan sukses:

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

Masalahnya, dan fakta bahwa itu diperbaiki di CU6, didokumentasikan dalam artikel KB berikut:
PERBAIKI: Kesalahan "Akses ditolak" ketika Anda mencoba membuat database di SQL Server 2017 Express LocalDB

Untuk mendapatkan Pembaruan Kumulatif, silakan kunjungi halaman berikut dan ambil build teratas (yaitu terbaru), yang mungkin lebih baru dari CU6 tergantung pada saat Anda melihat ini:

SQL Server 2017 membangun versi


DI BAWAH INFO OBSOLETE SEBAGAI SQL SERVER 2017 CU6 (Dirilis 2018-04-17)

Kurangnya backslash dalam gabungan Path + Nama file tampaknya menjadi bug dengan SQL Server 2017. Saya hanya berlari sendiri. Saya bahkan mencoba mengedit Registry untuk menambahkan DefaultDataNilai string untuk C: \ Users \ MyAccountName \ di kedua Kunci berikut (3 jalur default tidak ada di salah satu kunci registri LocalDB yang saya perhatikan):

  • Computer \ HKEY_CURRENT_USER \ Software \ Microsoft \ Microsoft SQL Server \ UserInances \ {some-GUID-value}
  • Komputer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL14E.LOCALDB \ MSSQLServer

Dan ya, saya melakukan shutdown dan memulai lagi contoh LocalDB dalam kedua upaya.

Namun, saya tidak yakin bahwa tidak dapat mengubah jalur default adalah bug karena mungkin saja dokumentasi yang buruk dan penanganan kesalahan yang buruk digabungkan. Saya mengatakan ini karena saya baru saja mencoba mengedit lokasi default untuk SQL Server versi LocalDB 2014, 2016, dan 2017, dan semua menghasilkan kesalahan yang sama persis, yang dengan sendirinya aneh karena berasal dari RegCreateKeyEx(), yang seharusnya berurusan dengan Registry dan bukan sistem file.

Tidak dapat mengubah jalur sangat disayangkan karena kurangnya backslash ketika membuat Database baru tanpa menentukan file yang akan digunakan. Namun, saya dapat membuat Database baru menggunakan CREATE DATABASEsintaks lengkap sebagai berikut:

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

Kami mengambil pendekatan dalam pengaturan basis data kami bahwa jika itu adalah koneksi LocalDb, kami menentukan jalur file MDF, seperti dalam solusi Anda. Tapi sepertinya tidak perlu juga menentukan nama LDF atau LOG ONbagian dari CREATE DATABASEpernyataan itu. File LDF tampaknya dibuat, secara default, di lokasi yang sama dengan file MDF. (Kasus penggunaan kami dari LocalDb terutama untuk digunakan dalam tes otomatis.)
tgharold

@tgharold Silakan lihat pembaruan di bagian atas jawaban saya. Bug ini baru-baru ini diperbaiki di patch CU6 baru :-).
Solomon Rutzky

5

Saya mengalami masalah yang sama dan menemukan solusi yang seharusnya tidak memiliki kekurangan yang jelas (jika saya lupa sesuatu, tolong perbaiki saya) . Ini didasarkan pada jawaban Solomon, tetapi tanpa perlu menentukan jalur absolut ke file database secara langsung.

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)

Ini menggunakan sql dinamis dan tidak persis cantik, tetapi menyelesaikan pekerjaan sampai ada perbaikan resmi untuk masalah ini.


1
Menarik. Ini mungkin menjadi sedikit lebih baik untuk memindahkan 2 QUOTENAMEke 2 param dari FORMATMESSAGEdan menempatkan tanda kutip ganda di sekitar path file: FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);. Tetapi tampaknya berfungsi seperti yang Anda miliki sekarang, jadi beri +1 untuk pendekatan ini. Masih ada kasus untuk pengkodean nama atau melewati jalur: ketika Anda tidak ingin menggunakan USERPROFILEroot. Tapi Anda bisa membiarkannya di sini dan hanya default InstanceDefaultDataPathjika @Path IS NULL. :-)
Solomon Rutzky

Terima kasih. Saya telah mengedit jawaban dengan saran Anda. Saya setuju hard-coding jalur absolut jelas masih merupakan solusi yang valid. Dalam skenario kami, kami hanya membuat ulang database selama pengujian otomatis dan saya harus memastikan itu akan bekerja untuk semua kolega saya dan membangun server, tanpa harus mengoordinasikan semua orang membuat folder di jalur yang sama persis pada mesin lokal mereka. :-)
Nikolaj Dam Larsen

4

Saya menghadapi masalah ini juga. Satu-satunya solusi yang saya temukan adalah memberikan akses tulis c:\Users\ke Semua Orang (atau sesuatu seperti itu) dan biarkan ia membuat file mdf di mana pun ia mau.


1
Terima kasih, ini menyelesaikannya untuk saya juga! Pemecahan masalah ini menyebalkan, tetapi hanya ada di server build lokal kami, jadi saya tidak peduli dengan hak pengguna tambahan.
Hannes Sachsenhofer

@ HannesSachsenhofer: Saya setuju, ini menyebalkan. Tapi saya dijanjikan oleh tim pengembang LocalDB mereka akan memperbaiki bug ini dalam rilis perbaikan terbaru mendatang.
abatishchev

Berikan akses menulis kepada semua orang sepertinya solusi yang sangat buruk bagi saya
Raphael

@ Raphael: Kenapa? Anda memiliki banyak pengguna di kotak dev Anda? Dan siapa yang tidak Anda percayai?
abatishchev

2

Terima kasih atas penjelasan singkat Anda tentang masalah ini. Saya mengalami masalah yang sama kemarin. Saya masih belum menemukan solusi permanen, tetapi inilah solusi saya saat ini.

Saya menggunakan fungsi Database.EnsureCreated () untuk membuat database.

Setel string koneksi untuk memasukkan pengaturan ' AttachDBFilename = '.

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

Jalankan aplikasi. Ini akan menghasilkan kesalahan:

Tidak dapat melampirkan file '. \ ExploreCalifornia.mdf' sebagai basis data 'ExploreCalifornia'.

tetapi itu akan membuat database.

Setelah itu, ubah string koneksi dan hapus ' AttachDBFilename = '.

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

Saya menjalankan aplikasi lagi tanpa kesalahan dan tabel dibuat.


Beberapa pertanyaan: Pertama, hanya untuk memastikan - Anda mendapatkan kesalahan (Akses ditolak) pada awalnya, dan ini menyelesaikannya, benar? Kedua - SQL Server Management Studio adalah satu-satunya aplikasi yang disebutkan oleh IP, dan ini tidak terdengar seperti sesuatu yang Anda lakukan dari sana - dari aplikasi apa Anda melakukan semua ini?
RDFozz

Terima kasih atas jawaban Anda, tetapi ini tidak benar-benar menyelesaikan masalah saya. Kode pengujian saya membuat database baru dengan sederhana CREATE DATABASE [databasename]terhadap LocalDB dan pernyataan ini menyebabkan masalah karena LocalDB salah menggabungkan direktori lokasi default dengan nama database yang dibuat secara acak (lihat paragraf 3 dan 4 pertanyaan saya). Saya perlu cara untuk memperbaiki lokasi default agar masalah penggabungan ini tidak terjadi.
feO2x

Saat ini, saya tidak dapat membuat database melalui SQL / DDL sama sekali. Tidak masalah jika saya menjalankan pernyataan melalui SSMS, atau dari kode, atau di mana pun, karena LocalDB selalu mencoba membuat database secara langsung di direktori Users (yang sepenuhnya salah, tidak ada file yang diizinkan ada di direktori ini) .
feO2x

1
Anda mungkin salah mengeja AttachDBFilename.
tgharold
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.