web-dev-qa-db-fra.com

Essayer de joindre un fichier mdf à localDb renvoie une erreur, au moins un fichier est requis

Here is error

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

16
Neeraj Sharma

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:

  1. 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');
  2. 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');
  3. Mettre hors ligne et remettre en ligne ou redémarrer SQL Server

    • Utilisation de SQL Server Management Studio:
      1. Cliquez avec le bouton droit sur la base de données renommée et cliquez sur Take Offline Sous Tasks.
      2. Cliquez avec le bouton droit sur la base de données (hors ligne) et cliquez sur Bring Online Sous Tasks.
    • Utilisation de T-SQL:
      1. ALTER DATABASE [CurrentName] SET OFFLINE WITH ROLLBACK IMMEDIATE; (Le met hors ligne et déconnecte tous les clients)
      2. 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;
22
Jesse

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

3
DeepSpace101

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):

  1. Après avoir ATTACHÉ les fichiers MDF et LDF avec succès, vous souhaitez créer un fichier BAK (sauvegarde) en sauvegardant la base de données.
  2. Ensuite, vous souhaitez supprimer/supprimer la base de données du serveur SQL.
  3. Ensuite, vous souhaitez restaurer la base de données. C'est ici que vous pouvez aller dans la section FICHIERS (à gauche) qui vous permettra de modifier le Restore As nom du fichier selon ce que vous voulez que les fichiers MDF et LDF soient nommés comme.
  4. Je voudrais ensuite continuer et faire une autre sauvegarde de cette nouvelle base de données afin que cette fois, la sauvegarde contienne les noms de fichiers corrects que vous souhaitez.
2
Arvo Bowen

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.

1
Sinjai

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
0
b_levitt