本文目录导读:

我来介绍几种批量附加数据库脚本的方法,主要针对SQL Server:
使用动态SQL批量附加
-- 批量附加同一目录下的多个数据库文件
DECLARE @sql NVARCHAR(MAX) = ''
DECLARE @DataFiles TABLE (FilePath NVARCHAR(500))
-- 假设MDF文件都在同一目录下
INSERT INTO @DataFiles
VALUES
('D:\Data\DB1.mdf'),
('D:\Data\DB2.mdf'),
('D:\Data\DB3.mdf'),
('D:\Data\DB4.mdf')
SELECT @sql = @sql +
'CREATE DATABASE [' +
REPLACE(REVERSE(LEFT(REVERSE(FilePath), CHARINDEX('\', REVERSE(FilePath))-1)), '.mdf', '') +
'] ON (FILENAME = N''' + FilePath + ''')' +
' FOR ATTACH;' + CHAR(13)
FROM @DataFiles
-- 执行批量附加
EXEC sp_executesql @sql
使用游标逐个处理
DECLARE @DataFile NVARCHAR(500)
DECLARE @LogFile NVARCHAR(500)
DECLARE @DBName NVARCHAR(100)
DECLARE @SQL NVARCHAR(MAX)
-- 创建临时表存储文件信息
CREATE TABLE #AttachFiles (
ID INT IDENTITY(1,1),
MDFPath NVARCHAR(500),
LDFPath NVARCHAR(500)
)
-- 插入要附加的数据库文件
INSERT INTO #AttachFiles (MDFPath, LDFPath)
VALUES
('D:\Data\DB1.mdf', 'D:\Data\DB1_log.ldf'),
('D:\Data\DB2.mdf', 'D:\Data\DB2_log.ldf'),
('D:\Data\DB3.mdf', 'D:\Data\DB3_log.ldf')
DECLARE @i INT = 1
DECLARE @maxID INT = (SELECT MAX(ID) FROM #AttachFiles)
WHILE @i <= @maxID
BEGIN
SELECT
@DataFile = MDFPath,
@LogFile = LDFPath,
@DBName = REPLACE(REPLACE(MDFPath, 'D:\Data\', ''), '.mdf', '')
FROM #AttachFiles
WHERE ID = @i
SET @SQL = 'CREATE DATABASE [' + @DBName + '] ON ' +
'(FILENAME = N''' + @DataFile + '''), ' +
'(FILENAME = N''' + @LogFile + ''') ' +
'FOR ATTACH;'
PRINT @SQL -- 可选:打印执行的SQL
EXEC sp_executesql @SQL
SET @i = @i + 1
END
DROP TABLE #AttachFiles
自动扫描目录附加
# PowerShell脚本 - 批量附加数据库
$server = "localhost"
$dataPath = "D:\Data"
$sql = ""
# 获取所有MDF文件
$mdfFiles = Get-ChildItem -Path $dataPath -Filter "*.mdf"
foreach ($mdf in $mdfFiles) {
$dbName = $mdf.BaseName
$mdfPath = $mdf.FullName
$ldfPath = $mdfPath.Replace(".mdf", "_log.ldf")
# 检查LDF文件是否存在
if (Test-Path $ldfPath) {
$sql += @"
CREATE DATABASE [$dbName] ON
(FILENAME = N'$mdfPath'),
(FILENAME = N'$ldfPath')
FOR ATTACH;
"@
} else {
$sql += @"
CREATE DATABASE [$dbName] ON
(FILENAME = N'$mdfPath')
FOR ATTACH;
"@
}
}
# 执行SQL
Invoke-Sqlcmd -ServerInstance $server -Query $sql
带有错误处理的脚本
-- 带错误处理和状态记录的批量附加脚本
CREATE PROC sp_BatchAttachDatabases
@DataPath NVARCHAR(500) = 'D:\Data'
AS
BEGIN
SET NOCOUNT ON
DECLARE @Result TABLE (
DBName NVARCHAR(100),
Status NVARCHAR(50),
ErrorMsg NVARCHAR(MAX)
)
DECLARE @Files TABLE (
RowID INT IDENTITY(1,1),
FileName NVARCHAR(500),
FullPath NVARCHAR(500)
)
-- 使用xp_cmdshell获取文件列表(需要开启xp_cmdshell)
INSERT INTO @Files (FileName, FullPath)
EXEC xp_cmdshell 'dir /b "D:\Data\*.mdf"'
DECLARE @RowID INT = 1
DECLARE @MaxID INT = (SELECT MAX(RowID) FROM @Files)
WHILE @RowID <= @MaxID
BEGIN
DECLARE @CurrentFile NVARCHAR(500)
DECLARE @DBName NVARCHAR(100)
DECLARE @SQL NVARCHAR(MAX)
DECLARE @ErrorMsg NVARCHAR(MAX) = ''
SELECT @CurrentFile = FullPath FROM @Files WHERE RowID = @RowID
-- 获取数据库名称
SET @DBName = REVERSE(LEFT(REVERSE(@CurrentFile),
CHARINDEX('\', REVERSE(@CurrentFile)) - 1))
SET @DBName = REPLACE(@DBName, '.mdf', '')
BEGIN TRY
SET @SQL = 'CREATE DATABASE [' + @DBName + '] ON ' +
'(FILENAME = N''' + @CurrentFile + ''') ' +
'FOR ATTACH'
EXEC sp_executesql @SQL
INSERT INTO @Result (DBName, Status, ErrorMsg)
VALUES (@DBName, 'Success', '')
END TRY
BEGIN CATCH
SET @ErrorMsg = ERROR_MESSAGE()
INSERT INTO @Result (DBName, Status, ErrorMsg)
VALUES (@DBName, 'Failed', @ErrorMsg)
END CATCH
SET @RowID = @RowID + 1
END
-- 显示结果
SELECT * FROM @Result
END
使用方法
- 方法一:适合已知具体文件列表的情况
- 方法二:适合需要逐个处理特殊情况
- 方法三:使用PowerShell,自动化程度高
- 方法四:适合生产环境,有错误处理
注意事项
- 文件权限:SQL Server服务账号需要有文件访问权限
- 数据库已存在:确保数据库名不重复
- 日志文件:某些情况下需要同时指定LDF文件
- 事务日志:大数据库附加可能需要较长时间
- 兼容性:SQL Server版本需与原数据库创建版本兼容
选择哪种方法取决于你的具体需求和环境配置。