如何编写批量文件附加数据库脚本

wen 实用脚本 1

本文目录导读:

如何编写批量文件附加数据库脚本

  1. 方法一:使用动态SQL批量附加
  2. 方法二:使用游标逐个处理
  3. 方法三:自动扫描目录附加
  4. 方法四:带有错误处理的脚本
  5. 使用方法
  6. 注意事项

我来介绍几种批量附加数据库脚本的方法,主要针对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

使用方法

  1. 方法一:适合已知具体文件列表的情况
  2. 方法二:适合需要逐个处理特殊情况
  3. 方法三:使用PowerShell,自动化程度高
  4. 方法四:适合生产环境,有错误处理

注意事项

  1. 文件权限:SQL Server服务账号需要有文件访问权限
  2. 数据库已存在:确保数据库名不重复
  3. 日志文件:某些情况下需要同时指定LDF文件
  4. 事务日志:大数据库附加可能需要较长时间
  5. 兼容性:SQL Server版本需与原数据库创建版本兼容

选择哪种方法取决于你的具体需求和环境配置。

抱歉,评论功能暂时关闭!