LocalDB v14 crée un mauvais chemin pour les fichiers mdf

34

Récemment, j'ai mis à niveau LocalDB de la version 13 à la version 14 à l'aide du programme d'installation de SQL Server Express et de cette instruction . Après l'installation, j'ai arrêté l'instance par défaut existante (MSSQLLOCALDB) de la version 13 et en ai créée une nouvelle, qui utilisait automatiquement le moteur de serveur v14.0.1000.

J'utilise souvent LocalDB pour les tests d'intégration de base de données, c'est-à-dire que, dans mes tests xunit, je crée une base de données (temporaire) qui est supprimée à la fin du test. Depuis la nouvelle version, tous mes tests ont malheureusement échoué à cause du message d'erreur suivant:

CREATE FILE a rencontré l'erreur 5 du système d'exploitation (accès refusé.) En essayant d'ouvrir ou de créer le fichier physique 'C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf'

Ce qui est étrange, c'est que le chemin cible du fichier mdf est incorrect, une barre oblique inverse est manquante entre C: \ Users \ kepfl et DBd0811493e18b46febf980ffb8029482a.mdf (nom de base de données aléatoire pour un seul test). Les bases de données sont créées via la commande simple CREATE DATABASE [databaseName]- rien de spécial ici.

Dans SSMS, je constate que les emplacements cibles pour les données, les journaux et les sauvegardes sont les suivants:

Emplacements cibles de LocalDB

Cependant, lorsque j'essaie de mettre à jour l'emplacement, j'obtiens un autre message d'erreur:

Message d'erreur lors de la tentative de mise à jour

Comment puis-je mettre à jour les emplacements par défaut afin que LocalDB puisse à nouveau créer des bases de données? Il est évident que LocalDB ne combine pas correctement le répertoire d’emplacement par défaut et le nom du fichier de base de données. Existe-t-il une entrée de registre que je puisse modifier? Ou autre chose?

Mise à jour après la réponse de Doug et le commentaire de Sepupic

Selon cette question de Stackoverflow , l'emplacement par défaut devrait également être modifiable via le registre. Cependant, si j'essaie de trouver les clés correspondantes "DefaultData", "DefaultLog" et "BackupDirectory", je ne les trouve pas dans mon registre. SQL Server v14 a-t-il renommé ces clés de registre ou déplacé ces informations hors du registre?

feO2x
la source
Pour votre information, je ne peux pas non plus mettre à jour les emplacements par défaut de la base de données lors de l'exécution de SSMS en mode administrateur.
feO2x
1
S'il vous plaît voir la mise à jour dans ma réponse. Ce bug a été corrigé à partir de CU6, publié mi-avril.
Solomon Rutzky

Réponses:

21

MISE À JOUR

À partir de la CU 6 pour SQL Server 2017, ce bogue a été corrigé. Il est maintenant possible d'exécuter les tâches suivantes avec succès:

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

Le problème et le fait qu'il est résolu dans CU6 sont décrits dans l'article de la base de connaissances suivant:
CORRECTIF: erreur "Accès refusé" lorsque vous essayez de créer une base de données dans SQL Server 2017 Express LocalDB

Pour obtenir la mise à jour cumulative, veuillez aller à la page suivante et récupérer la dernière version (la plus récente), qui peut être plus récente que CU6 selon le moment où vous voyez ceci:

Versions de construction de SQL Server 2017


CI-DESSOUS INFO OBSOLETE OF SQL SERVER 2017 CU6 (Paru le 2018-04-17)

L'absence de barre oblique inversée dans le nom combiné Chemin + Fichier semble constituer un bogue avec SQL Server 2017. Je viens de le rencontrer moi-même. J'ai même essayé d'éditer le registre pour ajouter une DefaultDatachaîne de caractères Value pour C: \ Users \ MyAccountName \ dans les deux clés suivantes (les 3 chemins par défaut ne figurent dans aucune des clés de registre LocalDB que j'ai consultées):

  • Ordinateur \ HKEY_CURRENT_USER \ Logiciel \ Microsoft \ Microsoft SQL Server \ UtilisateurInstances \ {valeur_GUID}
  • Ordinateur \ HKEY_LOCAL_MACHINE \ LOGICIEL \ Microsoft \ Microsoft SQL Server \ MSSQL14E.LOCALDB \ MSSQLServer

Et oui, j'ai arrêté et redémarré l'instance LocalDB dans les deux tentatives.

Cependant, je ne suis pas convaincu que le fait de ne pas pouvoir changer les chemins par défaut est un bogue, car il pourrait s'agir simplement d'une mauvaise documentation et d'une mauvaise gestion des erreurs combinées. Je dis cela parce que je viens d'essayer de modifier les emplacements par défaut pour les versions 2014, 2016 et 2017 de SQL Server LocalDB, et que tous aboutissaient à la même erreur, ce qui en soi est étrange en raison de son origine RegCreateKeyEx(), ce qui devrait traiter du registre et pas le système de fichiers.

Il est regrettable que le chemin ne puisse pas être modifié en raison de l'absence de barre oblique inverse lors de la création d'une nouvelle base de données sans spécifier les fichiers à utiliser. Cependant, j'ai pu créer une nouvelle base de données en utilisant l'intégralitéCREATE DATABASE syntaxe comme suit:

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
Salomon Rutzky
la source
Dans notre configuration de base de données, nous adoptons l’approche suivante: si c’est une connexion LocalDb, nous spécifions le chemin du fichier MDF, comme dans votre solution de contournement. Mais il ne semble pas nécessaire de spécifier également le nom du LDF ou la LOG ONsection de la CREATE DATABASEdéclaration. Les fichiers LDF semblent avoir été créés, par défaut, au même emplacement que le fichier MDF. (Notre cas d'utilisation de LocalDb est principalement destiné à être utilisé dans des tests automatisés.)
tgharold
@tgharold S'il vous plaît voir la mise à jour en haut de ma réponse. Ce bogue a été récemment corrigé dans le nouveau correctif CU6 :-).
Solomon Rutzky
5

J'ai rencontré le même problème et j'ai trouvé une solution de contournement qui ne devrait pas présenter d'inconvénient évident. (si j'oublie quelque chose, corrigez-moi, s'il vous plaît) . Il est basé sur la réponse de Solomons, mais sans la nécessité de spécifier directement le chemin absolu vers les fichiers de base de données.

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)

Il utilise SQL dynamique et n’est pas vraiment joli, mais il fait le travail jusqu’à ce qu’il y ait une solution officielle au problème.

Nikolaj Dam Larsen
la source
1
Intéressant. Il pourrait être légèrement mieux déplacer le 2ème QUOTENAMEau 2ème PARAM FORMATMESSAGEet mettre des guillemets doubles autour du chemin du fichier: FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);. Mais cela semble fonctionner comme vous l'avez maintenant, donc +1 pour cette approche. Il est toujours possible de coder en dur le nom ou de passer par un chemin: lorsque vous ne voulez pas utiliser la USERPROFILEracine. Mais vous pouvez autoriser cela ici et ne définir que InstanceDefaultDataPathsi @Path IS NULL. :-)
Solomon Rutzky
Merci. J'ai modifié la réponse avec votre suggestion. Je conviens que coder en dur le chemin absolu reste une solution valable. Dans notre scénario, cependant, nous ne recréons la base de données que lors de tests automatiques et je devais m'assurer que cela fonctionnerait pour tous mes collègues et créer un serveur, sans avoir à coordonner tout le monde créant un dossier exactement au même chemin sur leur ordinateur local. :-)
Nikolaj Dam Larsen
4

Je suis confronté à ce problème aussi. La seule solution que j'ai trouvée serait d'octroyer l'accès en écriture c:\Users\à Tout le monde (ou quelque chose du genre) et de le laisser créer les fichiers mdf où il le souhaite.

abatishchev
la source
1
Merci, cela a résolu pour moi aussi! Cette solution de contournement est nulle, mais elle ne concerne que notre serveur de génération local. Je ne me soucie donc pas des droits d'utilisateur supplémentaires.
Hannes Sachsenhofer
@HannesSachsenhofer: Je suis d'accord, ça craint. Mais l'équipe de développement de LocalDB m'a promis de corriger ce bogue dans la prochaine version du correctif logiciel.
Abatishchev
Accorder l'accès en écriture à tout le monde me semble une très mauvaise solution de contournement
Raphaël
@ Raphaël: Pourquoi? Vous avez plusieurs utilisateurs sur votre boîte de dev? Et à qui tu n'as pas confiance?
Abatishchev
2

Merci pour votre explication concise de ce problème. J'ai rencontré le même problème hier. Je n'ai toujours pas trouvé de solution permanente, mais voici ma solution de contournement actuelle.

J'utilise la fonction Database.EnsureCreated () pour créer la base de données.

Définissez la chaîne de connexion pour inclure le paramètre ' AttachDBFilename = '.

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

Lancer l'application. Cela va générer une erreur:

Impossible de joindre le fichier '. \ ExploreCalifornia.mdf' en tant que base de données 'ExploreCalifornia'.

mais cela créera la base de données.

Après cela, modifiez la chaîne de connexion et supprimez ' AttachDBFilename = '.

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

J'ai relancé l'application sans erreur et des tables ont été créées.

Doug Abrahamson
la source
Quelques questions: Tout d’abord, juste pour être sûr, vous obteniez initialement une erreur (accès refusé), et cela a résolu le problème, est-ce exact? Second - SQL Server Management Studio est la seule application mentionnée par l’IP, et cela ne ressemble pas à quelque chose que vous avez fait à partir de là. À partir de quelle application avez-vous fait tout cela?
RDFozz
Merci pour votre réponse, mais cela ne résout pas vraiment mon problème. Mon code de test crée une nouvelle base de données avec un simple CREATE DATABASE [databasename]contre LocalDB, ce qui pose problème, car LocalDB concatène à tort le répertoire des emplacements par défaut avec le nom de la base de données généré aléatoirement (voir paragraphes 3 et 4 de ma question). J'ai besoin d'un moyen de corriger les emplacements par défaut afin que ce problème de concaténation ne se produise pas.
feO2x
Actuellement, je ne suis pas du tout capable de créer une base de données via SQL / DDL. Peu importe si j'exécute l'instruction via SSMS, à partir de code ou ailleurs, car LocalDB essaie toujours de créer la base de données directement dans le répertoire Utilisateurs (ce qui est complètement faux, aucun fichier ne peut exister dans ce répertoire). .
feO2x
1
Vous avez peut-être mal orthographié AttachDBFilename.
tgharold