导航

SQL SERVER 快照维护 存储过程

Posted on 2021-05-16 20:46  yiyishuitian  阅读(99)  评论(0编辑  收藏  举报
SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO

--生成数据库快照
CREATE PROC [dbo].[CreateSnapshotForBackUp]
(
    --数据库名称
    @p_DateBaseName VARCHAR(100),
    --数据库快照文件位置,保留\字符
    @p_FilePath VARCHAR(2000),
    --保留最近N个快照,  下面代码是按名称排序的,也可以按创建日期排序.跟据自己需求来.
    @p_RetainN INT
)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @strSql VARCHAR(MAX);
    DECLARE @strDatetime VARCHAR(20);
    DECLARE @strDBFileName VARCHAR(200);
    --日期类别为YYYYmmDDHHMMSS
    SET @strDatetime = REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR, GETDATE(), 120), '-', ''), ' ', ''), ':', '');


    --如果存在此数据库则进行下面的操作
    IF
    (
        SELECT COUNT(*)FROM sys.databases WHERE name = @p_DateBaseName
    ) > 0
    BEGIN

        DECLARE @SnapshotName VARCHAR(1000) = @p_DateBaseName + '_snapshot_' + @strDatetime;
        DECLARE @fileName VARCHAR(1000) = @p_FilePath + @p_DateBaseName + '_snapshot_' + @strDatetime + '.ss';



        SET @strSql
            = CONCAT(
                        ' CREATE DATABASE ',
                        @SnapshotName,
                        ' ON (    NAME = ''',
                        @p_DateBaseName,
                        ''',FILENAME = ''',
                        @fileName,
                        ''' ) AS SNAPSHOT OF ',
                        @p_DateBaseName
                    );

        BEGIN TRY
            PRINT @strSql;
            EXEC (@strSql);
            PRINT @p_DateBaseName + ' snapshot create successful:' + @SnapshotName;

        END TRY
        BEGIN CATCH
            SELECT 'snapshot create fail:'+ERROR_MESSAGE()  throw;
        END CATCH;

    END;

    --删除过期的数据库快照
    BEGIN TRY
        IF OBJECT_ID('tempdb..#snapshotname') IS NOT NULL
            DROP TABLE #snapshotname;

        --取除最近的快照之外的快照名称,这里是按名称排序的. 也可以使用创建日期排序
        SELECT snapShot_database.name,
               ROW_NUMBER() OVER (ORDER BY snapShot_database.name DESC) id
        INTO #snapshotname
        FROM sys.databases AS source_database
            JOIN sys.databases AS snapShot_database
                ON source_database.database_id = snapShot_database.source_database_id
        WHERE source_database.name = @p_DateBaseName
        ORDER BY snapShot_database.name DESC OFFSET @p_RetainN ROW FETCH NEXT 100 ROWS ONLY;



        DECLARE @strDropDatabase VARCHAR(MAX) = '';

        --如果#snapshotname 存在记录则进行
        IF
        (
            SELECT COUNT(1)FROM #snapshotname
        ) > 0
        BEGIN


            SELECT @strDropDatabase = @strDropDatabase + ' DROP DATABASE ' + name + ' ; '
            FROM #snapshotname;

            EXEC (@strDropDatabase);

        END;

    END TRY
    BEGIN CATCH
        SELECT N'snapshot delete fail:'+ERROR_MESSAGE() throw;
    END CATCH;

END;
GO