¡Hola, chicos!
En el post de hoy me gustaría compartir una solución que creé para responder una pregunta en uno de los grupos de Telegram en los que participo, que era la pregunta de cómo saber cuánto tiempo ha estado en línea una base de datos en SQL Server. esto no es cuánto tiempo ha estado la instancia en línea y sí, cuánto tiempo lleva una base de datos en línea.

Para resolver esta pregunta, pensé en usar el registro de SQL Server para identificar cuándo se inició cada base de datos y devolvérselo al usuario. La siguiente consulta devolverá todas las bases de datos que se encuentran en el último archivo de registro, junto con la fecha en que se inicializó por última vez la base de datos y el tiempo transcurrido desde entonces hasta la hora actual.

IF (OBJECT_ID('tempdb..#StartupDB') IS NOT NULL) DROP TABLE #StartupDB
CREATE TABLE #StartupDB (
    [LogNumber] TINYINT,
    [LogDate] DATETIME,
    [ProcessInfo] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI, 
    [Text] NVARCHAR(MAX) COLLATE SQL_Latin1_General_CP1_CI_AI,
    [Database] AS (REPLACE(REPLACE(SUBSTRING([Text], CHARINDEX('''', [Text]), 128), '''', ''), '.', ''))
)

INSERT INTO #StartupDB (LogDate, ProcessInfo, [Text]) 
EXEC master.dbo.sp_readerrorlog 0, 1, N'Starting up database ', NULL

SELECT
    [Database],
    MAX(LogDate) AS LogDate,
    (CASE WHEN DATEDIFF(SECOND, MAX(LogDate), GETDATE()) > 86400 THEN CAST(DATEDIFF(SECOND, MAX(LogDate), GETDATE()) / 86400 AS VARCHAR) + 'd ' ELSE '' END) + 
    RIGHT('00' + CAST((DATEDIFF(SECOND, MAX(LogDate), GETDATE()) / 3600) % 24 AS VARCHAR), 2) + ':' + 
    RIGHT('00' + CAST((DATEDIFF(SECOND, MAX(LogDate), GETDATE()) / 60) % 60 AS VARCHAR), 2) + ':' + 
    RIGHT('00' + CAST(DATEDIFF(SECOND, MAX(LogDate), GETDATE()) % 60 AS VARCHAR), 2) + '.' + 
    RIGHT('000' + CAST(DATEDIFF(SECOND, MAX(LogDate), GETDATE()) AS VARCHAR), 3) 
    AS TimeRunning
FROM
    #StartupDB
GROUP BY
    [Database]
ORDER BY 1

Resultado:

Si desea analizar todo el historial de inicio de la base de datos, escaneando todos los archivos de registro (no solo el último):

IF (OBJECT_ID('tempdb..#Arquivos_Log') IS NOT NULL) DROP TABLE #Arquivos_Log
CREATE TABLE #Arquivos_Log ( 
    [idLog] INT, 
    [dtLog] NVARCHAR(30) COLLATE SQL_Latin1_General_CP1_CI_AI, 
    [tamanhoLog] INT 
)

IF (OBJECT_ID('tempdb..#StartupDB') IS NOT NULL) DROP TABLE #StartupDB
CREATE TABLE #StartupDB (
    [LogNumber] TINYINT,
    [LogDate] DATETIME, 
    [ProcessInfo] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI, 
    [Text] NVARCHAR(MAX) COLLATE SQL_Latin1_General_CP1_CI_AI,
    [Database] AS (REPLACE(REPLACE(SUBSTRING([Text], CHARINDEX('''', [Text]), 128), '''', ''), '.', ''))
)


INSERT INTO #Arquivos_Log
EXEC sys.sp_enumerrorlogs

DECLARE
    @Contador INT = 0,
    @Total INT = (SELECT COUNT(*) FROM #Arquivos_Log)
    
 
WHILE(@Contador < @Total)
BEGIN
    
    INSERT INTO #StartupDB (LogDate, ProcessInfo, [Text]) 
    EXEC master.dbo.xp_readerrorlog @Contador, 1, N'Starting up database ', NULL, NULL, NULL
 
    -- Atualiza o número do arquivo de log
    UPDATE #StartupDB
    SET LogNumber = @Contador
    WHERE LogNumber IS NULL
 
    SET @Contador += 1
    
END
 

SELECT * 
FROM #StartupDB
ORDER BY LogDate DESC

Resultado:

En las dos soluciones presentadas, puede utilizar la columna "Base de datos" para filtrar los bancos seleccionados y creo que la pregunta original fue respondida por estos 2 scripts.

¡Eso es todo, amigos! Espero que te haya gustado este consejo. ¿Conoce alguna otra solución para responder a esta pregunta? Déjalo aquí en los comentarios 🙂

¡Un abrazo grande y hasta la próxima!