LocalDB v14 crea una ruta incorrecta para archivos mdf

34

Recientemente, actualicé LocalDB de la versión 13 a la 14 usando el instalador de SQL Server Express y esta instrucción . Después de la instalación, detuve la instancia predeterminada existente (MSSQLLOCALDB) de la versión 13 y creé una nueva, que utilizaba automáticamente el motor del servidor v14.0.1000.

A menudo uso LocalDB para las pruebas de integración de la base de datos, es decir, en mis pruebas xunit, creo una base de datos (temporal) que se elimina cuando finaliza la prueba. Desde la nueva versión, desafortunadamente todas mis pruebas fallan debido al siguiente mensaje de error:

CREAR ARCHIVO encontró el error 5 del sistema operativo (acceso denegado) al intentar abrir o crear el archivo físico 'C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482a.mdf'

Lo extraño es que la ruta de destino para el archivo mdf es incorrecta, falta una barra invertida entre C: \ Users \ kepfl y DBd0811493e18b46febf980ffb8029482a.mdf (que es el nombre de la base de datos aleatoria para una sola prueba). Las bases de datos se crean mediante el comando simple CREATE DATABASE [databaseName], nada especial aquí.

En SSMS, veo que las ubicaciones de destino para datos, registro y copia de seguridad son las siguientes:

Ubicaciones de destino de LocalDB

Sin embargo, cuando intento actualizar la ubicación, recibo otro mensaje de error:

Mensaje de error al intentar actualizar

¿Cómo puedo actualizar las ubicaciones predeterminadas para que LocalDB pueda crear bases de datos nuevamente? Es obvio que LocalDB no combina correctamente el directorio de ubicación predeterminado y el nombre del archivo de la base de datos. ¿Hay alguna entrada de registro que pueda editar? ¿O algo más?

Actualización después de la respuesta de Doug y el comentario de Sepupic

De acuerdo con esta pregunta de Stackoverflow , la ubicación predeterminada también debe ser modificable a través del registro. Sin embargo, si trato de encontrar las claves correspondientes "DefaultData", "DefaultLog" y "BackupDirectory", no puedo encontrarlas en mi registro. ¿SQL Server v14 cambió el nombre de estas claves de registro o eliminó esta información del registro?

feO2x
fuente
Para su información, tampoco puedo actualizar las ubicaciones predeterminadas de la base de datos cuando ejecuto SSMS en modo administrador.
feO2x
1
Por favor, vea la actualización en mi respuesta. Este error se corrigió a partir de CU6, lanzado a mediados de abril.
Solomon Rutzky

Respuestas:

21

ACTUALIZAR

A partir de CU 6 para SQL Server 2017, este error se ha solucionado. Ahora es posible ejecutar lo siguiente con éxito:

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

El problema, y ​​el hecho de que se corrige en CU6, se documenta en el siguiente artículo de KB:
REVISIÓN: error "Acceso denegado" cuando intenta crear una base de datos en SQL Server 2017 Express LocalDB

Para obtener la actualización acumulativa, vaya a la página siguiente y tome la compilación superior (es decir, la última), que podría ser más nueva que CU6 dependiendo de cuándo vea esto:

Versiones de compilación de SQL Server 2017


ABAJO INFO OBSOLETO A PARTIR DEL SERVIDOR SQL 2017 CU6 (Lanzado 2018-04-17)

La falta de una barra diagonal inversa en el nombre combinado de Ruta + Archivo parece ser un error con SQL Server 2017. Me encontré con él. Incluso intenté editar el registro para agregar un DefaultDatavalor de cadena para C: \ Users \ MyAccountName \ en las dos claves siguientes (las 3 rutas predeterminadas no están en ninguna de las claves de registro de LocalDB que examiné):

  • Computadora \ HKEY_CURRENT_USER \ Software \ Microsoft \ Microsoft SQL Server \ UserInstances \ {algún-valor-GUID}
  • Computadora \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL14E.LOCALDB \ MSSQLServer

Y sí, apagué y volví a iniciar la instancia de LocalDB en ambos intentos.

Sin embargo, no estoy convencido de que no poder cambiar las rutas predeterminadas sea un error, ya que podría ser una mala documentación y un manejo de errores deficiente combinado. Digo esto porque acabo de intentar editar las ubicaciones predeterminadas para las versiones LocalDB de SQL Server 2014, 2016 y 2017, y todo resultó en el mismo error exacto, que en sí mismo es extraño debido a que es RegCreateKeyEx(), que debería tratar con el Registro y No es el sistema de archivos.

No es posible cambiar la ruta debido a la falta de barra invertida al crear una nueva Base de Datos sin especificar los archivos a usar. Sin embargo, pude crear una nueva Base de Datos usando la CREATE DATABASEsintaxis completa de la siguiente manera:

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
Solomon Rutzky
fuente
Estamos adoptando el enfoque en nuestra configuración de base de datos de que si se trata de una conexión LocalDb, especificamos la ruta del archivo MDF, al igual que en su solución. Pero no parece necesario especificar también el nombre del LDF o la LOG ONsección de la CREATE DATABASEdeclaración. Los archivos LDF parecen haberse creado, de forma predeterminada, en la misma ubicación que el archivo MDF. (Nuestro caso de uso de LocalDb es principalmente para uso en pruebas automatizadas.)
tgharold
@tgharold Por favor, vea la actualización en la parte superior de mi respuesta. Este error se corrigió recientemente en el nuevo parche CU6 :-).
Solomon Rutzky
5

Me encontré con el mismo problema y encontré una solución que no debería tener inconvenientes claros (si estoy olvidando algo, corrígeme) . Se basa en la respuesta de Solomons, pero sin la necesidad de especificar la ruta absoluta a los archivos de la base de datos directamente.

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)

Utiliza sql dinámico y no es exactamente bonito, pero hace el trabajo hasta que haya una solución oficial al problema.

Nikolaj Dam Larsen
fuente
1
Interesante. Que podría ser un poco mejor para mover el segundo QUOTENAMEal segundo parámetro de FORMATMESSAGEy poner comillas alrededor de la ruta del archivo: FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);. Pero parece funcionar como lo tiene ahora, por lo que +1 para este enfoque. Todavía hay un caso para codificar el nombre o pasar una ruta: cuando no desea usar la USERPROFILEraíz. Pero podría permitir eso aquí y simplemente predeterminarlo a InstanceDefaultDataPathif @Path IS NULL. :-)
Solomon Rutzky
Gracias. He editado la respuesta con tu sugerencia. Estoy de acuerdo en que codificar el camino absoluto definitivamente sigue siendo una solución válida. Sin embargo, en nuestro escenario, solo recreamos la base de datos durante las pruebas automáticas y tuve que asegurarme de que funcionaría para todos mis colegas y construir el servidor, sin tener que coordinar a todos creando una carpeta en la misma ruta en su máquina local. :-)
Nikolaj Dam Larsen
4

También estoy enfrentando este problema. La única solución que encontré sería otorgar el acceso de escritura c:\Users\a Todos (o algo así) y dejar que cree los archivos mdf donde quiera.

abatishchev
fuente
1
¡Gracias, esto también lo resolvió para mí! Esta solución alternativa apesta, pero solo está en nuestro servidor de compilación local, por lo que no me importan los derechos de usuario adicionales.
Hannes Sachsenhofer
@HannesSachsenhofer: Estoy de acuerdo, apesta. Pero el equipo de desarrollo de LocalDB me prometió que solucionarán este error en la próxima versión de reparación en caliente.
abatishchev
Otorgar acceso de escritura a todos me parece una solución bastante mala para mí
Rafael
@Raphael: ¿Por qué? ¿Tienes múltiples usuarios en tu caja de desarrollo? ¿Y en quién no confías?
abatishchev
2

Gracias por su concisa explicación de este problema. Me encontré con este mismo problema ayer. Todavía no he encontrado una solución permanente, pero aquí está mi solución actual.

Estoy usando la función Database.EnsureCreated () para crear la base de datos.

Establezca la cadena de conexión para incluir la configuración ' AttachDBFilename = '.

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

Ejecuta la aplicación. Generará un error:

No se puede adjuntar el archivo '. \ ExploreCalifornia.mdf' como base de datos 'ExploreCalifornia'.

pero creará la base de datos.

Después de eso, cambie la cadena de conexión y elimine ' AttachDBFilename = '.

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

Volví a ejecutar la aplicación sin errores y se crearon tablas.

Doug Abrahamson
fuente
Un par de preguntas: Primero, solo para estar seguro: inicialmente estaba recibiendo un error (Acceso denegado) y esto lo resolvió, ¿correcto? Segundo: SQL Server Management Studio es la única aplicación mencionada por la IP, y esto no suena como algo que hiciste desde allí: ¿desde qué aplicación hiciste todo esto?
RDFozz
Gracias por su respuesta, pero esto realmente no resuelve mi problema. Mi código de prueba crea una nueva base de datos con un simple CREATE DATABASE [databasename]contra LocalDB y esta misma declaración está causando problemas ya que LocalDB concatena erróneamente el directorio de ubicaciones predeterminado con el nombre de la base de datos generada aleatoriamente (vea los párrafos 3 y 4 de mi pregunta). Necesito una forma de arreglar las ubicaciones predeterminadas para que este problema de concatenación no ocurra.
feO2x
Actualmente, no puedo crear una base de datos a través de SQL / DDL en absoluto. No importa si ejecuto la declaración a través de SSMS, o desde el código, o en cualquier otro lugar, porque LocalDB siempre intenta crear la base de datos directamente en el directorio de Usuarios (lo cual es completamente incorrecto, no se permite que existan archivos en este directorio) .
feO2x
1
Posiblemente ha escrito mal AttachDBFilename.
tgharold