尝试将 mdf 文件附加到 localDb 会引发错误至少需要一个文件
Trying to attach mdf file to localDb throws error at least one file is required
TITLE: Microsoft SQL Server Management Studio
Attach database failed for Server '(localdb)\mssqllocaldb'. (Microsoft.SqlServer.Smo)
ADDITIONAL INFORMATION:
At least one file is needed for Database Attach. (Microsoft.SqlServer.Smo)
我正在尝试将此 .mdf
数据库文件附加到我的 LocalDb 实例。如果我也可以将它发送到 SQL 服务器,那很好。我在同一目录
中有 .ldf
个文件
为了完成 - 解决了(一半)问题并让您继续。
问题的另一个 "half" 是 - 如果您 最终 想要重命名物理数据库文件怎么办?答案在这个CodeProject post.
步骤:
ALTER DATABASE
设置新的 物理 文件名(数据文件和日志文件)
直到SQL服务器重启或数据库脱机并恢复在线后才会生效
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
再次设置新的 逻辑 文件名(同样是数据和日志文件)
立即生效
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName', NEWNAME = 'NewDbName');
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName_log', NEWNAME = 'NewDbName_log');
离线并恢复在线或重启SQL服务器
- 使用 SQL Server Management Studio:
- Right-click 在重命名的数据库上,然后单击
Tasks
下的 Take Offline
。
- Right-click 在(离线)数据库上并单击
Tasks
下的 Bring Online
。
- 使用T-SQL:
ALTER DATABASE [CurrentName] SET OFFLINE WITH ROLLBACK IMMEDIATE;
(将其设置为离线并断开所有客户端)
ALTER DATABASE [CurrentName] SET ONLINE;
完整代码:
-- 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;
我不得不 move/rename 数据库好几次了。如果您在同一条船上,这里有一个脚本,它使用变量来避免一遍又一遍地输入 new/old 名称。
它使用与 相同的逻辑,除了自动为您启动数据库备份。我假设您需要在 moving/renaming 物理文件后将其重新打开,因此删除了该语句。如果这个假设不正确,请发表评论。
但是,要在 SSMS 中反映逻辑重命名,您仍然需要 right click -> rename
。如果不使用下面的 EXECUTE
/REPLACE
方法,这似乎是一样的。
---------- 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
第一次回答,如有不足请见谅
None 这些答案很快就得到了答案,所以我想我会添加我的答案来指出我的发现(基于这里每个人的贡献)...
情况:
您有一个数据库文件和一个日志文件,但没有它们的备份。您正在尝试连接数据库(很可能是为了从发生故障的服务器中恢复)。
问题:
您已将 MDF 和 LDF 文件的名称更改为与原来不同的名称。您需要将它们重命名回原来的名称,然后尝试附加。
如何重命名数据库文件(最简单的方法):
- 成功附加 MDF 和 LDF 文件后
想通过备份数据库来制作一个BAK(备份)文件。
- 接下来您要从 SQL 服务器 drop/delete 数据库。
- 接下来您要还原数据库。这是您可以进入的地方
FILES 部分(左侧)可让您更改
Restore As
将 MDF 和 LDF 文件命名为您希望的文件名。
- 然后我会继续为那个新数据库做另一个备份
再次这样这次备份包含正确的文件名
你要。
如果您不记得以前的文件名,请在十六进制编辑器中打开 .mdf 文件,在大约偏移量 0x19D 处您将看到该文件名的 UTF-16 (2 byte/char) 字符串
命令行对重命名的文件更加宽容。请注意,这不是 fire-and-forget 脚本...运行 每个部分分开,注意需要更改的名称:
--#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
TITLE: Microsoft SQL Server Management Studio
Attach database failed for Server '(localdb)\mssqllocaldb'. (Microsoft.SqlServer.Smo)
ADDITIONAL INFORMATION:
At least one file is needed for Database Attach. (Microsoft.SqlServer.Smo)
我正在尝试将此 .mdf
数据库文件附加到我的 LocalDb 实例。如果我也可以将它发送到 SQL 服务器,那很好。我在同一目录
.ldf
个文件
为了完成 -
问题的另一个 "half" 是 - 如果您 最终 想要重命名物理数据库文件怎么办?答案在这个CodeProject post.
步骤:
ALTER DATABASE
设置新的 物理 文件名(数据文件和日志文件)
直到SQL服务器重启或数据库脱机并恢复在线后才会生效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
再次设置新的 逻辑 文件名(同样是数据和日志文件)
立即生效ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName', NEWNAME = 'NewDbName');
ALTER DATABASE [CurrentName] MODIFY FILE (NAME = 'CurrentName_log', NEWNAME = 'NewDbName_log');
离线并恢复在线或重启SQL服务器
- 使用 SQL Server Management Studio:
- Right-click 在重命名的数据库上,然后单击
Tasks
下的Take Offline
。 - Right-click 在(离线)数据库上并单击
Tasks
下的Bring Online
。
- Right-click 在重命名的数据库上,然后单击
- 使用T-SQL:
ALTER DATABASE [CurrentName] SET OFFLINE WITH ROLLBACK IMMEDIATE;
(将其设置为离线并断开所有客户端)ALTER DATABASE [CurrentName] SET ONLINE;
- 使用 SQL Server Management Studio:
完整代码:
-- 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;
我不得不 move/rename 数据库好几次了。如果您在同一条船上,这里有一个脚本,它使用变量来避免一遍又一遍地输入 new/old 名称。
它使用与
但是,要在 SSMS 中反映逻辑重命名,您仍然需要 right click -> rename
。如果不使用下面的 EXECUTE
/REPLACE
方法,这似乎是一样的。
---------- 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
第一次回答,如有不足请见谅
None 这些答案很快就得到了答案,所以我想我会添加我的答案来指出我的发现(基于这里每个人的贡献)...
情况:
您有一个数据库文件和一个日志文件,但没有它们的备份。您正在尝试连接数据库(很可能是为了从发生故障的服务器中恢复)。
问题:
您已将 MDF 和 LDF 文件的名称更改为与原来不同的名称。您需要将它们重命名回原来的名称,然后尝试附加。
如何重命名数据库文件(最简单的方法):
- 成功附加 MDF 和 LDF 文件后 想通过备份数据库来制作一个BAK(备份)文件。
- 接下来您要从 SQL 服务器 drop/delete 数据库。
- 接下来您要还原数据库。这是您可以进入的地方
FILES 部分(左侧)可让您更改
Restore As
将 MDF 和 LDF 文件命名为您希望的文件名。 - 然后我会继续为那个新数据库做另一个备份 再次这样这次备份包含正确的文件名 你要。
如果您不记得以前的文件名,请在十六进制编辑器中打开 .mdf 文件,在大约偏移量 0x19D 处您将看到该文件名的 UTF-16 (2 byte/char) 字符串
命令行对重命名的文件更加宽容。请注意,这不是 fire-and-forget 脚本...运行 每个部分分开,注意需要更改的名称:
--#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