AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 185909
Accepted
Francesco Mantovani
Francesco Mantovani
Asked: 2017-09-14 16:26:47 +0800 CST2017-09-14 16:26:47 +0800 CST 2017-09-14 16:26:47 +0800 CST

SQL Server: Como definir a hora em um formato legível por humanos

  • 772

Encontrei esta consulta útil aqui e a uso para monitorar trabalhos do SQL Server.

SELECT
sJobHis.[server],
sJobStep.database_name,
SJob.name,
SJob.enabled,
CASE WHEN SJob.enabled = 0 THEN '0'
WHEN sJobStep.subsystem = 'TSQL' AND sJobStep.command LIKE '%--%' 
AND AVG(CAST(SUBSTRING(STUFF(
            STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6)
                , 3, 0, ':')
            , 6, 0, ':') ,7,2) AS INT)) < 1 THEN '0'
WHEN sJobStep.subsystem = 'TSQL' AND sJobStep.command LIKE '%*/%'
AND AVG(CAST(SUBSTRING(STUFF(
            STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6)
                , 3, 0, ':')
            , 6, 0, ':') ,7,2) AS INT)) < 1
 THEN '0'
ELSE '1' END AS  [ActiveStep],
sLogin.name [JobOwner],
sJobHis.step_id,
sJobHis.step_name,
sJobStep.subsystem AS [CommandType],
sJobStep.command AS [Command],
sJobHis.run_date,
[sJobSch].next_run_time AS [Scheduled_Time],
--sJobHis.run_time,
--sJobHis.run_duration,
AVG( CAST( SUBSTRING(STUFF(
            STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6)
                , 3, 0, ':')
            , 6, 0, ':') ,4,2)AS INT))
       AS [AvgRunDuration_In_Min], 
AVG(CAST(SUBSTRING(STUFF(
            STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6)
                , 3, 0, ':')
            , 6, 0, ':') ,7,2) AS INT))
       AS [AvgRunDuration_In_Sec],
COUNT(*) AS [PerDay]
FROM sysjobs AS [SJob] 
LEFT JOIN sysjobhistory AS [sJobHis] ON SJob.job_id = sJobHis.job_id
LEFT JOIN sysjobsteps AS [sJobStep] ON sJobHis.job_id = sJobStep.job_id AND sJobHis.step_id = sJobStep.step_id
INNER JOIN master.dbo.syslogins [sLogin] ON SJob.owner_sid = sLogin.sid
INNER JOIN dbo.sysjobschedules [sJobSch] ON SJob.job_id = [sJobSch].job_id
WHERE  SJob.[enabled]=0 OR ( sJobHis.step_id > 0  AND (sJobHis.run_date > 20131002 AND sJobHis.run_date < 20131005)) 
GROUP BY sJobHis.[server],
sJobStep.database_name,
SJob.name,
SJob.enabled,
sLogin.name ,
sJobHis.step_id,
sJobHis.step_name,
sJobStep.subsystem ,
sJobStep.command ,
sJobHis.run_date,
[sJobSch].next_run_time
ORDER BY SJob.enabled DESC, SJob.name, sJobHis.run_date DESC

Eu gosto de ter uma visão geral do que está acontecendo no meu servidor, compre duas colunas que não significam nada para mim:

insira a descrição da imagem aqui

Eu gostaria de ter as colunas Scheduled_Timee Running_Timemais "legíveis para humanos", pois às vezes não consigo descobrir o que eles estão dizendo.

Às vezes eu vejo Scheduled_Timecomo 92000ou 121200e não tenho ideia do que isso significa.

Mesmo problema com o Running_Timequal às vezes mostra 120700ou 20000.

Não tenho ideia do que isso significa.

Eu não preciso ver os trabalhos com falha

A consulta que já tenho está perfeita, só quero formatar essas duas colunas em uma saída mais legível

sql-server jobs
  • 2 2 respostas
  • 775 Views

2 respostas

  • Voted
  1. clifton_h
    2017-09-14T23:50:30+08:002017-09-14T23:50:30+08:00

    O roteiro é terrível e a fonte... não tinha muita autoridade. :/

    Para ser justo com sua pergunta, monitorar trabalhos do SQL Server Agent não é tão simples quanto se poderia pensar, embora o tempo legível por humanos seja suspeito do autor das consultas.

    • As tabelas de trabalho do SQL Server Agent
    • [dbo].[sysjobactivity]

      Registra a atividade e o status atual do trabalho do SQL Server Agent.

      dbo.sysjobactivity | Documentos da Microsoft

    • [dbo].[sysjobhistory]

      Contém informações sobre a execução de trabalhos agendados pelo SQL Server Agent.

      NOTA: Os dados são atualizados somente após a conclusão da etapa de trabalho

      dbo.sysjobhistory | Documentos da Microsoft

    • [dbo].[sysjobs]

      Armazena as informações de cada trabalho agendado a ser executado pelo SQL Server Agent.

      dbo.sysjobs | Documentos da Microsoft

    • [dbo].[sysjobschedules]

      Contém informações de agendamento para trabalhos a serem executados pelo SQL Server Agent.

      NOTA: A tabela sysjobschedules é atualizada a cada 20 minutos, o que pode afetar os valores retornados pelo procedimento armazenado sp_help_jobschedule.

      dbo.sysjobschedules | Documentos da Microsoft

    • [dbo].[sysjobservers]

      Armazena a associação ou relacionamento de um determinado trabalho com um ou mais servidores de destino

      dbo.sysjobservers | Documentos da Microsoft

    • [dbo].[sysjobsteps]

      Contém as informações de cada etapa de um trabalho a ser executado pelo SQL Server Agent

      dbo.sysjobsteps | Documentos da Microsoft

    • [dbo].[sysjobstepslogs]

      Contém o log de etapas de trabalho para todas as etapas de trabalho do SQL Server Agent configuradas para gravar a saída da etapa de trabalho em uma tabela.

      dbo.sysjobstepslogs | Documentos da Microsoft

    • Como encontrar trabalhos com falha

    Como o objetivo é a saúde do servidor, tente focar em um dos trabalhos que estão realmente falhando. Concentrar-se nas médias é bom, mas não é muito útil, a menos que você seja o proprietário do aplicativo e precise conhecer esses detalhes minuciosos. Mas mesmo assim, desafie o pedido para descobrir o porquê.

    Me deparei com um excelente script que me permite encontrar todos os trabalhos com falha, a etapa em que falhou e todos os logs/mensagens relatados em nossos mais de 200 servidores .

    USE msdb
    GO
    /* Create #Temp table to house job events */
    IF EXISTS (SELECT 1 FROM tempdb.sys.tables WHERE NAme LIKE '#FailedJobs%')
        DROP TABLE #FailedJobs
    CREATE TABLE #FailedJobs (Job VARCHAR(250)
                            , StepFailed VARCHAR(100)
                            , DateRun VARCHAR(30)
                            , TimeRun VARCHAR(30)
                            , Step_name VARCHAR(100)
                            , run_Duration INT
                            , LogOutput VARCHAR(MAX) )
    
    DECLARE @JobName VARCHAR(250)
    DECLARE @job_id UNIQUEIDENTIFIER
    
    DECLARE JobsCursor CURSOR FORWARD_ONLY
    FOR SELECT Name 
        FROM sysjobs A 
        INNER JOIN dbo.sysjobschedules B ON A.job_id = B.job_id
        WHERE A.enabled = 1
            AND B.next_run_date > 0
    
        OPEN JobsCursor
        FETCH NEXT FROM JobsCursor INTO @JobName
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT @job_id = job_id FROM dbo.sysjobs WHERE [name] = @JobName        
        INSERT INTO #FailedJobs (Job, StepFailed, DateRun, TimeRun, Step_name, run_Duration, LogOutput )
    
        SELECT @JobName AS Job
            , 'Step ' + CAST(JH.step_id AS VARCHAR(3)) 
                + ' of ' + (    SELECT CAST(COUNT(*) AS VARCHAR(5)) 
                            FROM dbo.sysjobsteps 
                            WHERE job_id = @job_id
                            ) AS StepFailed
            , CAST(RIGHT(JH.run_date,2) AS CHAR(2)) 
                + '/' + CAST(SUBSTRING(CAST(JH.run_date AS CHAR(8)),5,2) AS CHAR(2)) 
                + '/' + CAST(LEFT(JH.run_date,4) AS CHAR(4)) AS DateRun
            , LEFT(RIGHT('0' + CAST(JH.run_time AS VARCHAR(6)),6),2) 
                + ':' + SUBSTRING(RIGHT('0' + CAST(JH.run_time AS VARCHAR(6)),6),3,2) 
                + ':' + LEFT(RIGHT('0' + CAST(JH.run_time AS VARCHAR(6)),6),2) AS TimeRun
            , JS.step_name 
            , JH.run_duration 
            , CASE WHEN JSL.[log] IS NULL THEN JH.[Message]
                   ELSE JSL.[log]
              END AS LogOutput
        FROM dbo.sysjobsteps JS 
        INNER JOIN dbo.sysjobhistory JH ON JS.job_id = JH.job_id 
                                       AND JS.step_id = JH.step_id 
        LEFT OUTER JOIN dbo.sysjobstepslogs JSL ON JS.step_uid = JSL.step_uid
        WHERE INSTANCE_ID > (SELECT MIN(INSTANCE_ID)
                             FROM (
                                    SELECT top (2) INSTANCE_ID, job_id
                                    FROM dbo.sysjobhistory
                                    WHERE job_id = @job_id
                                    AND STEP_ID = 0
                                    ORDER BY INSTANCE_ID desc
                                    ) A
                            ) 
            AND JS.step_id <> 0 
            AND JH.job_id = @job_id
            /*Status of the job execution:
                0 = Failed
                1 = Succeeded
                2 = Retry
                3 = Canceled
            https://learn.microsoft.com/en-us/sql/relational-databases/system-tables/dbo-sysjobhistory-transact-sql
            */
            AND JH.run_status = 0
        ORDER BY JS.step_id ASC
    
        FETCH NEXT FROM JobsCursor INTO @JobName
    END
    CLOSE JobsCursor
    DEALLOCATE JobsCursor
    
    SELECT * 
    FROM #FailedJobs
    

    O formato retornado é muito perspicaz: FailedJobExample

    Observe como essa saída é legível. Você pode não apenas ver qual tarefa está falhando, mas também o step_id em que ela falhou! O LogOutput retornará o erro, tudo isso acionável .

    Como você provavelmente desejará isso mais tarde, adicionei duas outras consultas que são úteis:

    1. Encontre o local do log de erros - especialmente quando as consultas acima são truncadas

    USE master
    GO
    EXEC xp_readerrorlog 0, 1, N'Logging SQL Server messages in file', NULL, NULL, NULL, N'asc' 
    

    https://www.mssqltips.com/sqlservertip/2506/identify-location-of-the-sql-server-error-log-file/

    2. Analise o trabalho de Program_Name em sys.dm_exec_requests e sys.dm_exec_sessions

    Sempre quis ver as sessões em que um trabalho está sendo executado e suas solicitações? bem, agora você pode verificar isso facilmente através de alguns scripts

    - Pré-Solução

    SELECT convert(varbinary(32), substring([Program_name], 30, 34), 1) AS Job_ID
         , sjob.name
         , s.*
    FROM sys.dm_exec_sessions s
    INNER JOIN sys.dm_exec_requests r ON s.session_id = r.session_id
    INNER JOIN msdb.dbo.sysjobs sjob 
        ON convert(varbinary(32), substring([Program_name], 30, 34), 1) = sjob.job_id
    WHERE program_name like 'SQLAgent - TSQL JobStep %';
    

    Consulta de problema

    Apenas analise a coluna Program_Name para recuperar o Job_ID e certifique-se de convertê-lo para o formulário VARBINARY. Observe também que você precisa especificar o tipo de conversão para 1!

    - Pós-Solução

    Consulta Resolvida

    Espero que isso o leve muito mais à frente e se concentre em informações acionáveis .

    • 2
  2. Best Answer
    Francesco Mantovani
    2018-08-31T20:41:25+08:002018-08-31T20:41:25+08:00

    Demorou 1 ano, mas eu tenho.

    Segui este Guia da Microsoft e consegui o que queria: agora posso filtrar o trabalho por data , hora e até duração .

    SELECT
    sJobHis.[server],
    sJobStep.database_name,
    SJob.name,
    SJob.enabled,
    --CASE WHEN SJob.enabled = 0 THEN '0'
    --WHEN sJobStep.subsystem = 'TSQL' AND sJobStep.command LIKE '%--%' 
    --AND AVG(CAST(SUBSTRING(STUFF(STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') ,7,2) AS INT)) < 1 THEN '0'
    --WHEN sJobStep.subsystem = 'TSQL' AND sJobStep.command LIKE '%*/%'
    --AND AVG(CAST(SUBSTRING(STUFF(STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') ,7,2) AS INT)) < 1 THEN '0' ELSE '1' END AS  [ActiveStep],
    sLogin.name [JobOwner],
    sJobHis.step_id,
    sJobHis.step_name,
    sJobStep.subsystem AS [CommandType],
    sJobStep.command AS [Command],
    sJobHis.run_date,
    --[sJobSch].next_run_time AS [Scheduled_Time],
    STUFF(STUFF(RIGHT(REPLICATE('0', 6) +  CAST([sJobSch].next_run_time as varchar(6)), 6), 3, 0, ':'), 6, 0, ':') 'Scheduled_Time',
    --sJobHis.run_time,
    --sJobHis.run_duration,
    STUFF(STUFF(RIGHT(REPLICATE('0', 6) +  CAST(sJobHis.run_time as varchar(6)), 6), 3, 0, ':'), 6, 0, ':') 'run_time',
    STUFF(STUFF(STUFF(RIGHT(REPLICATE('0', 8) + CAST(sJobHis.run_duration as varchar(8)), 8), 3, 0, ':'), 6, 0, ':'), 9, 0, ':') 'run_duration (DD:HH:MM:SS)',
    --AVG( CAST( SUBSTRING(STUFF(STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') ,4,2)AS INT)) AS [AvgRunDuration_In_Min], 
    --AVG(CAST(SUBSTRING(STUFF(STUFF(RIGHT('000000' + CAST([sJobHis].[run_duration] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') ,7,2) AS INT)) AS [AvgRunDuration_In_Sec],
    COUNT(*) AS [PerDay]
    
    FROM msdb.dbo.sysjobs AS [SJob] 
    LEFT JOIN msdb.dbo.sysjobhistory AS [sJobHis] ON SJob.job_id = sJobHis.job_id
    LEFT JOIN msdb.dbo.sysjobsteps AS [sJobStep] ON sJobHis.job_id = sJobStep.job_id AND sJobHis.step_id = sJobStep.step_id
    INNER JOIN master.dbo.syslogins [sLogin] ON SJob.owner_sid = sLogin.sid
    INNER JOIN msdb.dbo.sysjobschedules [sJobSch] ON SJob.job_id = [sJobSch].job_id
    WHERE  SJob.[enabled]=0 OR ( sJobHis.step_id > 0  AND (sJobHis.run_date > 20180825 AND sJobHis.run_date < 20180829)) -- PUT HERE YOUR DATES
    GROUP BY sJobHis.[server],
    sJobStep.database_name,
    SJob.name,
    SJob.enabled,
    sLogin.name ,
    sJobHis.step_id,
    sJobHis.step_name,
    sJobStep.subsystem ,
    sJobStep.command ,
    sJobHis.run_date,
    sJobHis.run_time,
    sJobHis.run_duration,
    [sJobSch].next_run_time
    ORDER BY SJob.enabled DESC, SJob.name, sJobHis.run_date DESC
    

    Eu mantive as fileiras antigas para que você possa ver a mudança que fiz.

    insira a descrição da imagem aqui

    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve