LocalDB v14 crea un percorso errato per i file mdf


34

Di recente, ho aggiornato LocalDB dalla versione 13 alla 14 utilizzando il programma di installazione di SQL Server Express e queste istruzioni . Dopo l'installazione, ho arrestato l'istanza predefinita esistente (MSSQLLOCALDB) della versione 13 e ne ho creata una nuova, che utilizzava automaticamente il motore del server v14.0.1000.

Uso spesso LocalDB per i test di integrazione del database, ovvero nei test xunit, creo un database (temporaneo) che viene eliminato al termine del test. Dalla nuova versione, purtroppo tutti i miei test falliscono a causa del seguente messaggio di errore:

CREATE FILE ha riscontrato l'errore 5 del sistema operativo (accesso negato.) Durante il tentativo di aprire o creare il file fisico 'C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf'

La cosa strana è che il percorso target per il file mdf non è corretto, manca una barra rovesciata tra C: \ Users \ kepfl e DBd0811493e18b46febf980ffb8029482a.mdf (che è il nome del database casuale per un singolo test). I database vengono creati tramite il semplice comando CREATE DATABASE [databaseName]: qui nulla di speciale.

In SSMS, vedo che le posizioni di destinazione per dati, registro e backup sono le seguenti:

Posizioni target di LocalDB

Tuttavia, quando provo ad aggiornare la posizione, ricevo un altro messaggio di errore:

Messaggio di errore durante il tentativo di aggiornamento

Come posso aggiornare i percorsi predefiniti in modo che LocalDB sia in grado di creare nuovamente i database? È ovvio che LocalDB non combina correttamente la directory di posizione predefinita e il nome del file di database: esiste una voce di registro che posso modificare? O qualsiasi altra cosa?

Aggiornamento dopo la risposta di Doug e il commento di sepupic

In base a questa domanda StackOverflow , anche la posizione predefinita dovrebbe essere modificabile tramite il registro. Tuttavia, se provo a trovare le chiavi corrispondenti "DefaultData", "DefaultLog" e "BackupDirectory", non riesco a trovarle nel mio registro. SQL Server v14 ha rinominato queste chiavi di registro o ha spostato queste informazioni dal registro?


Cordiali saluti, inoltre, non riesco ad aggiornare le posizioni predefinite del database quando eseguo SSMS in modalità amministratore.
feO2x

1
Si prega di consultare l'aggiornamento nella mia risposta. Questo bug è stato corretto a partire da CU6, rilasciato a metà aprile ..
Solomon Rutzky,

Risposte:


21

AGGIORNARE

A partire da CU 6 per SQL Server 2017, questo errore è stato corretto. È ora possibile eseguire correttamente quanto segue:

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

Il problema e il fatto che sia stato risolto in CU6 è documentato nel seguente articolo KB:
FIX: errore "Accesso negato" quando si tenta di creare un database in SQL Server 2017 Express LocalDB

Per ottenere l'aggiornamento cumulativo, vai alla pagina seguente e prendi la build superiore (ovvero l'ultima), che potrebbe essere più recente di CU6 a seconda di quando vedi questo:

Versioni della build di SQL Server 2017


SOTTO INFO OBSOLETO COME DA SQL SERVER 2017 CU6 (Rilasciato il 17-04-2018)

La mancanza di una barra rovesciata nel nome Path + File combinato sembra essere un bug con SQL Server 2017. Mi sono appena imbattuto da solo. Ho anche provato a modificare il Registro di sistema per aggiungere un DefaultDatavalore stringa per C: \ Users \ MyAccountName \ in entrambe le seguenti chiavi (i 3 percorsi predefiniti non si trovano in nessuna delle chiavi del Registro di sistema LocalDB che ho cercato):

  • 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

E sì, ho fatto l'arresto e riavviato l'istanza LocalDB in entrambi i tentativi.

Tuttavia, non sono convinto che non essere in grado di modificare i percorsi predefiniti sia un bug in quanto potrebbe essere solo una scarsa documentazione e una cattiva gestione degli errori combinati. Dico questo perché ho appena provato a modificare i percorsi predefiniti per le versioni di SQL Server LocalDB 2014, 2016 e 2017 e tutti hanno provocato lo stesso errore esatto, che di per sé è strano a causa della provenienza RegCreateKeyEx(), che dovrebbe occuparsi del Registro di sistema e non il file system.

Non essere in grado di cambiare il percorso è sfortunato a causa della mancanza di barra rovesciata durante la creazione di un nuovo database senza specificare i file da utilizzare. Tuttavia, sono stato in grado di creare un nuovo database utilizzando la CREATE DATABASEsintassi completa come segue:

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

Stiamo adottando l'approccio nella nostra configurazione del database che, se si tratta di una connessione LocalDb, specifichiamo il percorso del file MDF, proprio come nella soluzione alternativa. Ma non sembra necessario specificare anche il nome dell'LDF o la LOG ONsezione CREATE DATABASEdell'istruzione. I file LDF sembrano essere creati, per impostazione predefinita, nella stessa posizione del file MDF. (Il nostro caso d'uso di LocalDb è principalmente per l'uso in test automatizzati.)
tgharold,

@tgharold Vedi l'aggiornamento nella parte superiore della mia risposta. Questo bug è stato corretto di recente nella nuova patch CU6 :-).
Solomon Rutzky,

5

Ho riscontrato lo stesso problema e ho trovato una soluzione alternativa che non dovrebbe presentare chiari inconvenienti (se dimentico qualcosa, correggimi) . Si basa sulla risposta di Solomons, ma senza la necessità di specificare direttamente il percorso assoluto dei file del database.

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)

Utilizza sql dinamico e non è esattamente carino, ma fa il lavoro fino a quando non c'è una soluzione ufficiale al problema.


1
Interessante. Esso potrebbe essere un po 'meglio per passare il 2 ° QUOTENAMEal 2 ° param di FORMATMESSAGEe mettere le virgolette doppie in tutto il percorso del file: FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);. Ma sembra funzionare come lo hai ora, quindi +1 per questo approccio. C'è ancora un caso per codificare il nome o passare in un percorso: quando non si desidera utilizzare il USERPROFILEroot. Ma potresti permetterlo qui e per impostazione predefinita InstanceDefaultDataPathse @Path IS NULL. :-)
Solomon Rutzky

Grazie. Ho modificato la risposta con il tuo suggerimento. Concordo sul fatto che il percorso assoluto sia sicuramente una soluzione valida. Nel nostro scenario, però, ricreamo il database solo durante i test automatici e ho dovuto assicurarmi che funzionasse per tutti i miei colleghi e costruire server, senza dover coordinare tutti creando una cartella nello stesso identico percorso sul loro computer locale. :-)
Nikolaj Dam Larsen

4

Sto affrontando anche questo problema. L'unica soluzione che ho trovato sarebbe quella di concedere l'accesso in scrittura c:\Users\a Everyone (o qualcosa del genere) e lasciarlo creare i file mdf dove vuole.


1
Grazie, questo ha risolto anche per me! Questa soluzione alternativa fa schifo, ma è solo sul nostro server di build locale, quindi non mi interessano i diritti utente aggiuntivi.
Hannes Sachsenhofer,

@HannesSachsenhofer: sono d'accordo, fa schifo. Ma mi è stato promesso dal team di sviluppo di LocalDB che risolveranno questo bug nella prossima versione di hotfix.
abatishchev,

Concedere l'accesso in scrittura a tutti mi sembra una pessima soluzione alternativa
Raphael

@Raphael: Perché? Hai più utenti sulla tua casella di sviluppo? E di chi non ti fidi?
abatishchev

2

Grazie per la tua concisa spiegazione di questo problema. Ho incontrato questo stesso problema ieri. Non ho ancora trovato una soluzione permanente, ma ecco la mia soluzione attuale.

Sto usando la funzione Database.EnsureCreated () per creare il database.

Impostare la stringa di connessione per includere l'impostazione ' AttachDBFilename = '.

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

Esegui l'applicazione. Si genererà un errore:

Impossibile allegare il file ". \ ExploreCalifornia.mdf" come database "ExploreCalifornia".

ma creerà il database.

Successivamente, modifica la stringa di connessione e rimuovi ' AttachDBFilename = '.

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

Ho eseguito nuovamente l'applicazione senza errori e sono state create tabelle.


Un paio di domande: in primo luogo, giusto per essere sicuri - inizialmente stavi ricevendo un errore (Accesso negato), e questo ha risolto il problema, giusto? Secondo: SQL Server Management Studio è l'unica applicazione menzionata dall'IP, e questo non suona come qualcosa che hai fatto da lì - da quale applicazione hai fatto tutto questo?
RDFozz,

Grazie per la tua risposta, ma questo non risolve davvero il mio problema. Il mio codice di test crea un nuovo database con un semplice CREATE DATABASE [databasename]contro LocalDB e questa affermazione sta causando problemi poiché LocalDB concatena erroneamente la directory dei percorsi predefinita con il nome del database generato casualmente (vedere i paragrafi 3 e 4 della mia domanda). Ho bisogno di un modo per correggere le posizioni predefinite in modo che questo problema di concatenazione non si verifichi.
feO2x

Al momento, non sono affatto in grado di creare un database tramite SQL / DDL. Non importa se eseguo l'istruzione tramite SSMS, o da codice o altrove, poiché LocalDB cerca sempre di creare il database direttamente nella directory Users (che è completamente errato, non è consentito l'esistenza di file in questa directory) .
feO2x

1
Probabilmente hai sbagliato l'ortografia AttachDBFilename.
tgharold,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.