Executar JOB com servidores distribuidos (LINKED SERVER)

Olá pessoal,

Ontem tivemos um problema aqui com a restauração de um DB, apesar de todo monitoramento por algum motivo ele não vinha restaurando desde o dia 04/04, enfim para auditar isso, eu criei uma tabela que armazena o valor somado de duas colunas, cada uma em um banco separado, o de origem e o de destino, como o fluxo de uso nessas tabelas é apenas em horário comercial, e o backup e restore são feitos de madrugada, o valor “NAQUELE” momento é igual, eu criei um banco de log que armazeno todos os logs que preciso de todos os sistemas.

USE [dblog]
GO

CREATE TABLE [dbo].[tb_LOG_Manutencao](
[id_Log] [int] IDENTITY(,) NOT NULL,
[NomeTabela_Banco] [nvarchar](0) NOT NULL,
[NomeTabela_Banco2] [nvarchar](0) NOT NULL,
[ValorCampo_Banco] [decimal](, 2) NULL,
[ValorCampo_Banco2] [decimal](, 2) NULL,
[NomeCampo_Banco] [nvarchar](max) NULL,
[NomeCampo_Banco2] [nvarchar](max) NULL,
[Validacao] [bit] NULL,
[Data] [datetime] NULL,
CONSTRAINT [PK_tb_LOG_Manutencao] PRIMARY KEY CLUSTERED

  (
  [id_Log] ASC
  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

Bom,

[id_Log] – ID,

[NomeTabela_Banco1] [nvarchar](70)  Nome da tabela do banco 1 a ser comparada,

[NomeTabela_Banco2] [nvarchar](70)  Nome da tabela do banco 2 a ser comparada,

[ValorCampo_Banco1] [decimal](18, 2) Valor resultante de uma soma pois escolhi uma coluna do banco 1 de valores pagos.

[ValorCampo_Banco2] [decimal](18, 2) Valor resultante de uma soma pois escolhi uma coluna do banco 2 de valores pagos.

[NomeCampo_Banco1] [nvarchar](max) Campo para comparação de string do banco 1

[NomeCampo_Banco2] [nvarchar](max) Campo para comparação de string do banco 2

[Validacao] [bit] – Recebe 1 para sucesso ou 0 para falha na comparação

[Data] [datetime] Data e hora da comparação

Após isso, criei uma procedure que faz a comparação e em seguida envia o e-mail com o resultado do sucesso ou falha da comparação após a execução do job da restauração do backup.

CREATE PROCEDURE [dbo].[dbCompare]
AS
    BEGIN

        DECLARE @vBanco1 INT ,
            @vBanco2 INT ,
            @Valida INT ,
            @INDICADOR NVARCHAR(8) ,
            @CORPOEMAIL NVARCHAR(MAX) ,
            @ASSUNTO NVARCHAR(MAX)

        SET NOCOUNT ON;

        SELECT  @vBanco1 = SUM(valorpago)
        FROM    Servidor1.Banco1.dbo.tabela
        WHERE   campo_restritivo >= 'valor'
        SELECT  @vBanco2 = SUM(valorpago)
        FROM    Banco2.dbo.tabela
        WHERE   campo_restritivo >= 'valor'

        IF @vBanco1 <> @vBanco2
            BEGIN
                SET @Valida = 0
                SET @INDICADOR = 'FALHA!'
            END
        ELSE
            BEGIN
                SET @Valida = 1
                SET @INDICADOR = 'SUCESSO!'
            END

        INSERT  INTO tb_log_manutencao
                ( NomeTabela_Banco1 ,
                  NomeTabela_Banco1 ,
                  vBanco1 ,
                  vBanco2 ,
                  Validacao
                )
        VALUES  ( 'tabela' ,
                  'tabela' ,
                  @vBanco1 ,
                  @vBanco2 ,
                  @Valida
                )

        SET @ASSUNTO = 'Notificação - Banco1 || Banco2 [' + @INDICADOR + ']'
        SET @CORPOEMAIL = N'<HTML><HEAD><TITLE>Notificação - Banco1 || Banco2</TITLE>'
            + N'<style type="text/css">.style1{font-size: x-small;font-family: Verdana;}'
            + N'.style2{font-weight: bold;}.style3{color: #CC0000;}</style></HEAD>'
            + N'<BODY><table>' + N'<tr><td>[Tabela - Banco1]:</td><td>'
            + CONVERT(VARCHAR, @vBanco1) + '</td></tr>'
            + N'<tr><td>[Tabela - Banco2]:</td><td>'
            + CONVERT(VARCHAR, @vBanco2) + '</td></tr>'
            + N'<tr><td>Resultado</td><td><strong>' + @INDICADOR
            + '</strong></td></tr>' + N'<tr><td>Data / Hora</td><td>'
            + CONVERT(NVARCHAR(30), GETDATE(), 109) + '</td></tr>'
            + N'</table></BODY></HTML>'

        EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Nome_Servico',
            @recipients = 'seu_email', @copy_recipients = 'email_copia',
            @body = @CORPOEMAIL, @subject = @ASSUNTO, @body_format = 'HTML';

    END

Depois disso eu configurei o JOB de Restauração e ai começou o problema por que tudo correu bem até a hora de executar a chamada da procedure, retornava o seguinte erro.

Mensagem
Executed as user: AUTORIDADE NT\SYSTEM. Login failed for user
'DOMINIO\SERVIDOR$'. [SQLSTATE 28000] (Error 18456).
The step failed.

O problema acontece por que é necessário ter um usuário com permissão no acesso ao servidor remoto, no entanto quando executava a procedure diretamente funcionava mas dentro do JOB não.
Após inúmeras pesquisas e muitas voltas, a solução é a extremamente simples.

Basta usar:

 1: EXECUTE AS LOGIN = 'usuario'
 2: go

Esse comando executa a chamada da procedure diretamente como [usuário], esse usuário deve existir em todos os servidores com as devidas permissões.

Tudo funcionando e usuários felizes !

Anúncios
Executar JOB com servidores distribuidos (LINKED SERVER)

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s