【问题标题】:Using T-SQL is there a way to show the name of a database being backed up or restored?使用 T-SQL 有没有办法显示正在备份或恢复的数据库的名称?
【发布时间】:2019-03-05 14:09:43
【问题描述】:

我有一些用于监控备份和恢复的代码,请给我一个“微软分钟”,了解它何时可能完成,运行了多长时间,以及其他一些信息。代码如下:

WITH CTE
AS (
SELECT @@SERVERNAME AS [ServerName]
    ,db_name(r.database_id) AS DatabaseName
    ,CONVERT(NUMERIC(6, 2), r.percent_complete) AS [PercentComplete]
    ,CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time, GetDate()), 20) AS [ETACompletionTime]
    ,CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [ElapsedMinutes]
    ,CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0 / 60.0) AS [ElapsedHours]
    ,CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETAMinutes]
    ,CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0 / 60.0) AS [ETAHours]
    ,CONVERT(VARCHAR(1000), (
            SELECT SUBSTRING(TEXT, r.statement_start_offset / 2, CASE 
                        WHEN r.statement_end_offset = - 1
                            THEN 1000
                        ELSE (r.statement_end_offset - r.statement_start_offset) / 2
                        END)
            FROM sys.dm_exec_sql_text(sql_handle) --sql_handle is a column from sys.dm_exec_requests
            )) AS [TSQLCode]
FROM sys.dm_exec_requests r
WHERE command IN (
        'RESTORE DATABASE'
        ,'BACKUP DATABASE'
        )
)
SELECT [ServerName]
,SUBSTRING([TSQLCode], CHARINDEX('DATABASE [', [TSQLCode]) + 10, CHARINDEX(']', [TSQLCode], (CHARINDEX('DATABASE [', [TSQLCode]) + 10)) - (CHARINDEX('DATABASE [', [TSQLCode]) + 10)) AS [DatabaseName]
,[PercentComplete]
,[ETACompletionTime]
,[ElapsedMinutes]
,[ElapsedHours]
,[ETAMinutes]
,[ETAHours]
,Cast(CASE 
        WHEN charindex('Rest', [TSQLCode], 0) > 0
            THEN 'Restoring'
        ELSE 'Backup'
        END AS VARCHAR(10)) AS BackupRestore
,[TSQLCode]
FROM CTE

这段代码大部分都可以工作...只要数据库用[databasename](方括号)封装。如果不是,您将收到以下错误。

对于我们必须恢复的所有数据库,以及我们拥有的许多正在执行恢复的作业,我不知道哪些作业有或没有方括号。而且我必须考虑到可能不使用方括号的人的临时备份\恢复作业。

所以我正在寻找一种无需解析即可获取正在备份或恢复的数据库的方法。

【问题讨论】:

    标签: sql-server tsql database-backups database-restore


    【解决方案1】:

    patindex('%DATABASE[ \[]%', [TSQLCode]) 交换 charindex 会弄乱你的 +10,可能更容易替换备份数据库和恢复数据库,ltrim 和 charindex ' ' 来拉后面的词。我没有测试下面的“代码”,但它看起来对我来说是正确的。随意摆弄!

    left(ltrim(replace(replace(TSQLCode, 'backup database',''),'restore database','')),charindex(' ',ltrim(replace(replace(TSQLCode, 'backup database',''),'restore database',''))))
    

    编辑:现在我面前有 sql server,试试:

    WITH CTE
    AS (
    SELECT @@SERVERNAME AS [ServerName]
        ,db_name(r.database_id) AS DatabaseName
        ,CONVERT(NUMERIC(6, 2), r.percent_complete) AS [PercentComplete]
        ,CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time, GetDate()), 20) AS [ETACompletionTime]
        ,CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [ElapsedMinutes]
        ,CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0 / 60.0) AS [ElapsedHours]
        ,CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETAMinutes]
        ,CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0 / 60.0) AS [ETAHours]
        ,replace(replace(CONVERT(VARCHAR(1000), (
                SELECT replace(replace(replace(replace(replace(replace(SUBSTRING(TEXT, r.statement_start_offset / 2, CASE 
                            WHEN r.statement_end_offset = - 1
                                THEN 1000
                            ELSE (r.statement_end_offset - r.statement_start_offset) / 2
                            END),']',''),'[',''),char(10),' '),char(13), ' '),char(9), ' '),'  ',' ')
                FROM sys.dm_exec_sql_text(sql_handle) --sql_handle is a column from sys.dm_exec_requests
                )),'  ',' '),'  ',' ') AS [TSQLCode]
    FROM sys.dm_exec_requests r
    WHERE command IN (
            'RESTORE DATABASE'
            ,'BACKUP DATABASE'
            )
    )
    SELECT [ServerName]
    ,SUBSTRING([TSQLCode], CHARINDEX('DATABASE ', [TSQLCode]) + 9, CHARINDEX(' ', [TSQLCode], (CHARINDEX('DATABASE ', [TSQLCode]) + 9)) - (CHARINDEX('DATABASE ', [TSQLCode]) + 9)) AS [DatabaseName]
    ,[PercentComplete]
    ,[ETACompletionTime]
    ,[ElapsedMinutes]
    ,[ElapsedHours]
    ,[ETAMinutes]
    ,[ETAHours]
    ,Cast(CASE 
            WHEN charindex('Rest', [TSQLCode], 0) > 0
                THEN 'Restoring'
            ELSE 'Backup'
            END AS VARCHAR(10)) AS BackupRestore
    ,[TSQLCode]
    FROM CTE
    

    更新为删除 (\n\r\t)(新行、回车、制表符)和“尝试”以清理足够多的双空格,以免影响您的输出。

    知道您的ascii table 是一件好事。

    删除 cte 中的 [],然后处理没有 [],在这里进行了我的测试。

    【讨论】:

    • 就目前而言,在没有方括号的备份代码上使用时没有错误,但它会在数据库名称之后拾取单词 TO。使用方括号,根本没有数据库名称。我正在接受你的建议并摆弄它。看起来是一个很好的起点。将报告调查结果。欢迎使用 StackOverflow。
    • 感谢您的欢迎!只迟到了 20 年,虽然不知道当时是否有 SO。我在答案中放了一个代码更改最少的工作示例,而不是使用 patindex(),只是删除括号并根据需要进行处理以丢失它们。根据我的测试结果,它会起作用。
    • 现在可以正常工作了!谢谢!我今天刚刚发现的另一件事是,如果 t-sql 代码以任何方式格式化(例如数据库名称后的回车以将代码放在下一行),它将弄乱您为我修复的内容。不知道如何解释。但是你让我进入了下一个障碍。再次感谢!
    • 在答案中添加了“修复”:) 双空格是魔鬼....我为它们做了 3 次替换,但它们仍然有可能出现。愚蠢。应该适用于所有格式选择的 99.999%。
    猜你喜欢
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多