TITRE: Microsoft SQL Server Management Studio
Échec de l'attachement de la base de données pour le serveur '(localdb)\mssqllocaldb'. (Microsoft.SqlServer.Smo)
INFORMATION ADDITIONNELLE:
Au moins un fichier est nécessaire pour Database Attach. (Microsoft.SqlServer.Smo)
J'essaie de joindre ce .mdf
fichier de base de données sur mon instance LocalDb. C'est bien si je peux aussi le faire sur SQL Server. J'ai .ldf
fichier dans le même répertoire
Pour le bien de l'achèvement - commentaire de Jim résout (la moitié) le problème et vous permet de continuer.
L'autre "moitié" du problème est - et si vous finalement voulez renommer le fichier de base de données physique? La réponse est disponible dans ce CodeProject post .
Pas:
ALTER DATABASE
Pour définir les nouveaux noms de fichiers physiques (fichier de données et fichier journal)
ne prend effet que lorsque SQL Server est redémarré ou que la base de données est mise hors ligne et remise en ligne
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName', FILENAME = '<Full-Path-Required>\NewDbName.mdf');
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName_log', FILENAME = '<Full-Path-Required>\NewDbName_log.ldf');
ALTER DATABASE
À nouveau pour définir de nouveaux noms de fichiers logique (à nouveau, fichiers de données et journaux)
prend effet immédiatement
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName', NEWNAME = 'NewDbName');
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName_log', NEWNAME = 'NewDbName_log');
Mettre hors ligne et remettre en ligne ou redémarrer SQL Server
Take Offline
Sous Tasks
.Bring Online
Sous Tasks
.ALTER DATABASE [CurrentName] SET OFFLINE WITH ROLLBACK IMMEDIATE;
(Le met hors ligne et déconnecte tous les clients)ALTER DATABASE [CurrentName] SET ONLINE;
Code complet:
-- Find "CurrentName" (without quotes) and replace with the current database name
-- Find "NewDbName" (without quotes) and replace with the new database name
USE [CurrentName];
-- Change physical file names:
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName', FILENAME = '<Full-Path-Required>\NewDbName.mdf');
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName_log', FILENAME = '<Full-Path-Required>\NewDbName_log.ldf');
-- Change logical names:
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName', NEWNAME = 'NewDbName');
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName_log', NEWNAME = 'NewDbName_log');
-- Take offline and back online
USE [master]
GO
ALTER DATABASE [CurrentName] SET OFFLINE WITH ROLLBACK IMMEDIATE;
-- Then navigate to <Full-Path-Required> and rename the files
ALTER DATABASE [CurrentName] SET ONLINE;
Si vous ne vous souvenez pas des noms de fichiers précédents, ouvrez le fichier .mdf dans un éditeur hexadécimal et autour de l'offset 0x19D, vous verrez une chaîne UTF-16 (2 octets/char) de ce nom de fichier
Aucune de ces réponses n'a été rapide pour les réponses au point, donc j'ai pensé que j'ajouterais simplement ma réponse pour souligner mes conclusions (sur la base des contributions de chacun ici) ...
La situation:
Vous disposez d'un fichier de base de données et d'un fichier journal, mais pas de sauvegarde. Vous essayez de FIXER la base de données (plus que probablement dans le but de récupérer à partir d'un serveur qui est tombé en panne).
Le problème:
Vous avez changé le nom des fichiers MDF et LDF en quelque chose de différent de ce qu'ils étaient à l'origine. Vous devez les renommer en leur donnant les noms d'origine, puis essayez de FIXER.
Comment renommer les fichiers DB (le plus simple):
Restore As
nom du fichier selon ce que vous voulez que les fichiers MDF et LDF soient nommés comme.J'ai dû déplacer/renommer des bases de données plusieurs fois. Si vous êtes dans le même bateau, voici un script qui utilise des variables pour éviter de taper les nouveaux/anciens noms encore et encore.
Il utilise la même logique de réponse de Jesse , autre que le démarrage automatique de la sauvegarde de la base de données pour vous. Je suppose que vous devez le réactiver après déplacer/renommer les fichiers physiques, d'où la suppression de cette déclaration. Veuillez commenter si cette hypothèse est incorrecte.
Cependant, pour refléter le renommage logique dans SSMS, vous devez toujours right click -> rename
. Cela semble être le même sans utiliser la méthode EXECUTE
/REPLACE
ci-dessous.
---------- CHANGE THESE ----------
-- Keep names identical to only move locations
DECLARE @CurrDbName AS varchar(255) = 'CurrentDbName'
DECLARE @NewDbName AS varchar(255) = 'NewDbName'
DECLARE @PathToFolder AS varchar(255) = '<FullPathMinusFilename>\'
---------- DECLARE TEMPLATES ----------
-- Use DB
DECLARE @USE_DB AS varchar(255) = 'USE [{CurrDbName}]'
-- Change physical file names
DECLARE @SET_PHYS_MDF AS varchar(255) = 'ALTER DATABASE [{CurrDbName}] MODIFY FILE (NAME = ''{CurrDbName}'', FILENAME = ''{PathToFolder}{NewDbName}.mdf'')'
DECLARE @SET_PHYS_LDF AS varchar(255) = 'ALTER DATABASE [{CurrDbName}] MODIFY FILE (NAME = ''{CurrDbName}_log'', FILENAME = ''{PathToFolder}{NewDbName}_log.ldf'')'
-- Change logical names (LOG = "logical", not "log")
If (@CurrDbName != @NewDbName)
BEGIN
DECLARE @SET_LOG_MDF AS varchar(255) = 'ALTER DATABASE [{CurrDbName}] MODIFY FILE (NAME = ''{CurrDbName}'', NEWNAME = ''{NewDbName}'')'
DECLARE @SET_LOG_LDF AS varchar(255) = 'ALTER DATABASE [{CurrDbName}] MODIFY FILE (NAME = ''{CurrDbName}_log'', NEWNAME = ''{NewDbName}_log'')'
END
-- Take offline
DECLARE @SET_OFFLINE AS varchar(255) = 'ALTER DATABASE [{CurrDbName}] SET OFFLINE WITH ROLLBACK IMMEDIATE'
---------- START DOING STUFF ----------
DECLARE @SQL_SCRIPT AS varchar(255)
-- Use DB
SET @SQL_SCRIPT = REPLACE(@USE_DB, '{CurrDbName}', @CurrDbName)
EXECUTE (@SQL_SCRIPT)
-- Change physical file names
SET @SQL_SCRIPT = REPLACE(REPLACE(REPLACE(@SET_PHYS_MDF, '{CurrDbName}', @CurrDbName), '{NewDbName}', @NewDbName), '{PathToFolder}', @PathToFolder)
EXECUTE (@SQL_SCRIPT)
SET @SQL_SCRIPT = REPLACE(REPLACE(REPLACE(@SET_PHYS_LDF, '{CurrDbName}', @CurrDbName), '{NewDbName}', @NewDbName), '{PathToFolder}', @PathToFolder)
EXECUTE (@SQL_SCRIPT)
-- Change logical names (LOG = "logical", not "log")
If (@CurrDbName != @NewDbName)
BEGIN
SET @SQL_SCRIPT = REPLACE(REPLACE(@SET_LOG_MDF, '{CurrDbName}', @CurrDbName), '{NewDbName}', @NewDbName)
EXECUTE (@SQL_SCRIPT)
SET @SQL_SCRIPT = REPLACE(REPLACE(@SET_LOG_LDF, '{CurrDbName}', @CurrDbName), '{NewDbName}', @NewDbName)
EXECUTE (@SQL_SCRIPT)
END
-- Take offline
USE [master]
SET @SQL_SCRIPT = REPLACE(@SET_OFFLINE, '{CurrDbName}', @CurrDbName)
EXECUTE (@SQL_SCRIPT)
-- Now turn off the database, rename/move physical files, and bring the database back online
Ceci est ma première réponse, je m'excuse si ce n'est pas de qualité suffisante.
La ligne de commande s'est avérée beaucoup plus indulgente avec les fichiers renommés. Notez que ce n'est pas un script à tirer et à oublier ... exécutez chaque partie séparément, en faisant attention aux noms qui doivent être modifiés:
--#1 Attach the db
USE [master]
GO
CREATE DATABASE RenamedDB ON
( FILENAME = N'<PathToRenamedFile>\renamedDBFile.mdf' ),
( FILENAME = N'<PathToRenamedFile>\renamedDBFile_log.ldf' )
FOR ATTACH
GO
--#2 Get the old logical file names:
USE RenamedDB
select * from sys.database_files
--#3 Rename the old logical files
ALTER DATABASE RenamedDB MODIFY FILE (NAME=N'OldLogicalDBName', NEWNAME=N'renamedDBFile')
GO
ALTER DATABASE RenamedDB MODIFY FILE (NAME=N'OldLogicalLogName', NEWNAME=N'renamedDBFile_log')
GO
--#4 check for the new names
select * from sys.database_files