LocalDB v14 tạo đường dẫn sai cho các tệp mdf


34

Gần đây, tôi đã nâng cấp LocalDB từ phiên bản 13 lên 14 bằng trình cài đặt SQL Server Express và hướng dẫn này . Sau khi cài đặt, tôi dừng phiên bản mặc định hiện tại (MSSQLLOCALDB) của phiên bản 13 và tạo một phiên bản mới, tự động sử dụng công cụ máy chủ v14.0.1000.

Tôi thường sử dụng các bài kiểm tra Tích hợp Cơ sở dữ liệu của LocalDB, tức là trong các bài kiểm tra xunit của tôi, tôi tạo một cơ sở dữ liệu (tạm thời) bị xóa khi kiểm tra kết thúc. Kể từ phiên bản mới, thật không may, tất cả các thử nghiệm của tôi đều thất bại vì thông báo lỗi sau:

CREATE FILE gặp phải lỗi hệ điều hành 5 (Truy cập bị từ chối.) Trong khi cố gắng mở hoặc tạo tệp vật lý 'C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf'

Điều kỳ lạ là đường dẫn đích cho tệp mdf không chính xác, dấu gạch chéo ngược bị thiếu giữa C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf (là tên cơ sở dữ liệu ngẫu nhiên cho một thử nghiệm). Các cơ sở dữ liệu được tạo thông qua lệnh đơn giản CREATE DATABASE [databaseName]- không có gì đặc biệt ở đây.

Trong SSMS, tôi thấy rằng các vị trí mục tiêu cho dữ liệu, nhật ký và sao lưu là như sau:

Các vị trí mục tiêu của LocalDB

Tuy nhiên, khi tôi cố cập nhật vị trí, tôi nhận được một thông báo lỗi khác:

Thông báo lỗi khi cố cập nhật

Làm cách nào tôi có thể cập nhật các vị trí mặc định để LocalDB có thể tạo lại cơ sở dữ liệu? Rõ ràng là LocalDB không kết hợp chính xác thư mục vị trí mặc định và tên tệp cơ sở dữ liệu - có mục đăng ký nào tôi có thể chỉnh sửa không? Hay bất cứ điều gì khác?

Cập nhật sau câu trả lời của Doug và bình luận của sepupic

Theo câu hỏi Stackoverflow này , vị trí mặc định cũng có thể được thay đổi thông qua sổ đăng ký. Tuy nhiên, nếu tôi cố gắng tìm các khóa tương ứng "DefaultData", "DefaultLog" và "BackupDirectory", tôi không thể tìm thấy chúng trong sổ đăng ký của mình. SQL Server v14 đã đổi tên các khóa đăng ký này hay đã chuyển các thông tin này ra khỏi sổ đăng ký?


FYI, tôi cũng không thể cập nhật các vị trí mặc định của Cơ sở dữ liệu khi chạy SSMS ở chế độ quản trị viên.
feO2x

1
Xin vui lòng xem cập nhật trong câu trả lời của tôi. Lỗi này đã được sửa từ CU6, được phát hành vào giữa tháng 4 ..
Solomon Rutzky

Câu trả lời:


21

CẬP NHẬT

Kể từ CU 6 cho SQL Server 2017, lỗi này đã được sửa. Bây giờ có thể thực hiện thành công sau đây:

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

Vấn đề và thực tế là nó đã được sửa trong CU6, được ghi lại trong bài viết KB sau:
Lỗi: Truy cập bị từ chối "khi bạn cố gắng tạo cơ sở dữ liệu trong SQL Server 2017 Express LocalDB

Để có được Cập nhật tích lũy, vui lòng truy cập trang sau và lấy bản dựng hàng đầu (tức là mới nhất), có thể mới hơn CU6 tùy thuộc vào thời điểm bạn thấy điều này:

Phiên bản xây dựng SQL Server 2017


DƯỚI ĐÂY THÔNG TIN LIÊN QUAN ĐẾN SQL SERVER 2017 CU6 (Phát hành 2018-04-17)

Việc thiếu dấu gạch chéo ngược trong tên Đường dẫn + Tệp kết hợp dường như là một lỗi với SQL Server 2017. Tôi chỉ tự mình chạy vào nó. Tôi thậm chí đã thử chỉnh sửa Sổ đăng ký để thêm một DefaultDatachuỗi Giá trị cho C: \ Users \ MyAccountName \ trong cả hai Khóa sau (3 đường dẫn mặc định không có trong bất kỳ khóa đăng ký LocalDB nào tôi đã xem qua):

  • Máy tính \ HKEY_CURRENT_USER \ Software \ Microsoft \ Microsoft SQL Server \ UserInstances \ {some-GUID-value}
  • Máy tính \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL14E.LOCALDB \ MSSQLServer

Và vâng, tôi đã tắt máy và khởi động lại cá thể LocalDB trong cả hai lần thử.

Tuy nhiên, tôi không tin rằng việc không thể thay đổi các đường dẫn mặc định là một lỗi vì nó có thể chỉ là tài liệu kém và xử lý lỗi kém kết hợp. Tôi nói điều này bởi vì tôi vừa thử chỉnh sửa các vị trí mặc định cho SQL Server LocalDB phiên bản 2014, 2016 và 2017, và tất cả đều dẫn đến cùng một lỗi chính xác, đó là lỗi kỳ lạ do RegCreateKeyEx()phải xử lý với Registry và không phải hệ thống tập tin.

Không thể thay đổi đường dẫn là không may do thiếu dấu gạch chéo ngược khi tạo Cơ sở dữ liệu mới mà không chỉ định các tệp sẽ sử dụng. Tuy nhiên, tôi đã có thể tạo Cơ sở dữ liệu mới bằng CREATE DATABASEcú pháp đầy đủ như sau:

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

Chúng tôi đang thực hiện phương pháp tiếp cận trong thiết lập cơ sở dữ liệu của mình rằng nếu đó là kết nối LocalDb, chúng tôi sẽ chỉ định đường dẫn của tệp MDF, giống như trong cách giải quyết của bạn. Nhưng dường như không cần thiết phải chỉ định tên của LDF hoặc LOG ONphần của CREATE DATABASEtuyên bố. Các tệp LDF dường như được tạo, theo mặc định, ở cùng vị trí với tệp MDF. (Trường hợp sử dụng LocalDb của chúng tôi chủ yếu được sử dụng trong các thử nghiệm tự động.)
tgharold 28/12/17

@tgharold Xin vui lòng xem bản cập nhật ở đầu câu trả lời của tôi. Lỗi này gần đây đã được sửa trong bản vá CU6 mới :-).
Solomon Rutzky

5

Tôi gặp vấn đề tương tự và tìm thấy một cách giải quyết không nên có bất kỳ nhược điểm rõ ràng nào (nếu tôi quên điều gì đó, xin vui lòng sửa lại cho tôi) . Nó dựa trên câu trả lời của Solomons, nhưng không cần chỉ định đường dẫn tuyệt đối đến các tệp cơ sở dữ liệu.

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)

Nó sử dụng sql động và không chính xác, nhưng nó hoàn thành công việc cho đến khi có một sửa chữa chính thức cho vấn đề.


1
Hấp dẫn. Có thể tốt hơn một chút để di chuyển thông số thứ 2 QUOTENAMEsang thông số thứ 2 FORMATMESSAGEvà đặt dấu ngoặc kép xung quanh đường dẫn tệp : FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);. Nhưng nó dường như hoạt động như bạn có bây giờ, vì vậy +1 cho phương pháp này. Vẫn còn một trường hợp cho việc mã hóa tên cứng hoặc chuyển qua một đường dẫn: khi bạn không muốn sử dụng USERPROFILEroot. Nhưng bạn có thể cho phép điều đó ở đây và chỉ mặc định là InstanceDefaultDataPathnếu @Path IS NULL. :-)
Solomon Rutzky

Cảm ơn bạn. Tôi đã chỉnh sửa câu trả lời với đề nghị của bạn. Tôi đồng ý mã hóa cứng đường dẫn tuyệt đối chắc chắn vẫn là một giải pháp hợp lệ. Mặc dù trong kịch bản của chúng tôi, chúng tôi chỉ tạo lại cơ sở dữ liệu trong quá trình kiểm tra tự động và tôi phải đảm bảo rằng nó sẽ hoạt động cho tất cả các đồng nghiệp của tôi và xây dựng máy chủ, mà không phải phối hợp mọi người tạo một thư mục theo cùng một đường dẫn trên máy cục bộ của họ. :-)
Nikolaj Dam Larsen

4

Tôi cũng đang đối mặt với vấn đề này. Cách giải quyết duy nhất tôi tìm thấy là cấp quyền truy cập ghi c:\Users\cho Mọi người (hoặc đại loại như thế) và để nó tạo các tệp mdf bất cứ nơi nào nó muốn.


1
Cảm ơn, điều này đã giải quyết nó cho tôi là tốt! Cách giải quyết này rất tệ, nhưng nó chỉ có trên máy chủ xây dựng cục bộ của chúng tôi, vì vậy tôi không quan tâm đến các quyền người dùng bổ sung.
Hannes Sachsenhofer

@HannesSachsenhofer: Tôi đồng ý, nó thật tệ. Nhưng tôi đã được nhóm nhà phát triển LocalDB hứa rằng họ sẽ sửa lỗi này trong phiên bản sửa lỗi nóng sắp tới.
abatishchev

Cấp quyền truy cập viết cho mọi người có vẻ như là một cách giải quyết khá tệ đối với tôi
Raphael

@Raphael: Tại sao? Bạn có nhiều người dùng trên hộp dev? Và người mà bạn không tin tưởng?
abatishchev

2

Cảm ơn bạn đã giải thích ngắn gọn về vấn đề này. Tôi đã gặp vấn đề tương tự ngày hôm qua. Tôi vẫn chưa tìm được giải pháp lâu dài, nhưng đây là cách giải quyết hiện tại của tôi.

Tôi đang sử dụng hàm Database.EnsureCreated () để tạo cơ sở dữ liệu.

Đặt chuỗi kết nối để bao gồm cài đặt ' AttachDBFilename = '.

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

Chạy ứng dụng. Nó sẽ tạo ra một lỗi:

Không thể đính kèm tệp '. \ ExploreCalifornia.mdf' làm cơ sở dữ liệu 'ExploreCalifornia'.

nhưng nó sẽ tạo ra cơ sở dữ liệu.

Sau đó, thay đổi chuỗi kết nối và xóa ' AttachDBFilename = '.

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

Tôi chạy lại ứng dụng mà không có lỗi và các bảng được tạo.


Một vài câu hỏi: Đầu tiên, chỉ để chắc chắn - ban đầu bạn đã nhận được một lỗi (Truy cập bị từ chối) và điều này đã giải quyết điều đó, đúng không? Thứ hai - SQL Server Management Studio là ứng dụng duy nhất được đề cập bởi IP và điều này không giống với những gì bạn đã làm từ đó - bạn đã làm tất cả những ứng dụng này từ đâu?
RDFozz

Cảm ơn câu trả lời của bạn, nhưng điều này không thực sự giải quyết vấn đề của tôi. Mã kiểm tra của tôi tạo ra một cơ sở dữ liệu mới đơn giản CREATE DATABASE [databasename]chống lại LocalDB và chính câu lệnh này đang gây ra vấn đề vì LocalDB kết hợp sai thư mục vị trí mặc định với tên cơ sở dữ liệu được tạo ngẫu nhiên (xem đoạn 3 và 4 câu hỏi của tôi). Tôi cần một cách để khắc phục các vị trí mặc định để vấn đề nối này không xảy ra.
feO2x

Hiện tại, tôi không thể tạo cơ sở dữ liệu thông qua SQL / DDL. Sẽ không có vấn đề gì nếu tôi chạy câu lệnh thông qua SSMS hoặc từ mã hoặc bất kỳ nơi nào khác, vì LocalDB luôn cố gắng tạo cơ sở dữ liệu trực tiếp trong thư mục Người dùng (hoàn toàn sai, không có tệp nào được phép tồn tại trong thư mục này) .
feO2x

1
Bạn có thể đã viết sai chính tả AttachDBFilename.
tgharold
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.