Você está offline; aguardando reconexão

Trabalhos do SQL Server Agent falham quando os trabalhos contêm etapas de trabalho que usam tokens após você instalar o SQL Server 2005 Service Pack 1

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 915845
Bug #: 426808 (SQLBUDT)
Sintomas
Depois de instalar o Microsoft SQL Server 2005 Service Pack 1 (SP1), você enfrentar o seguinte comportamento:
  • Trabalhos do SQL Server Agent falham quando os trabalhos contêm etapas de trabalho que usam tokens.
  • Você receber a seguinte mensagem de erro:
    A etapa de trabalho contém um ou mais símbolos. Para SQL Server 2005 Service Pack 1 ou posterior, todas as etapas de trabalho com tokens devem ser atualizadas com uma macro antes que o trabalho possa ser executado.
Observação Esse problema ocorre com compilação 2046 ou posteriores versões do SQL Server 2005.
Causa
No SQL Server 2005 SP1, a sintaxe de token de etapa do trabalho SQL Server Agent foi alterada. Agora, você deve incluir uma macro de escape com todos os tokens que são usados nas etapas de trabalho. Se você não incluir uma macro de escape, essas etapas de trabalho irão falhar. A tabela a seguir lista as macros de escape.
Macro de escapeDescrição
$ (ESCAPE_SQUOTE (TokenName))Essa macro escapes apóstrofos (') na seqüência de token de substituição. A macro substitui um apóstrofo dois apóstrofos.
$ (ESCAPE_DQUOTE (TokenName))Essa macro escapes entre aspas ("") na seqüência de token de substituição. A macro substitui uma aspa duas aspas.
$ (ESCAPE_RBRACKET (TokenName))Essa macro escapes colchetes direito (]) na seqüência de token de substituição. A macro substitui um colchete direito dois colchetes à direita.
$ (ESCAPE_NONE (TokenName))A macro substitui um token sem qualquer caracteres na seqüência de saída. Essa macro é fornecida para dar suporte à compatibilidade com versões anteriores em ambientes onde seqüências de token de substituição são esperadas somente de usuários confiáveis.
Por exemplo, uma etapa de trabalho pode conter a seguinte instrução Transact-SQL que usa o token A DBN :
CREATE DATABASE [$(A-DBN)]
neste exemplo, você deve atualizar a sintaxe de token para a seguinte sintaxe:
CREATE DATABASE [$(ESCAPE_RBRACKET(A-DBN))]
essa alteração difere do comportamento anterior do SQL Server 2005, onde as macros de escape não eram exigidas.
Resolução
Para resolver esse problema, atualize qualquer todos ou apenas trabalhos específicos que usam tokens para a nova sintaxe token. Para fazer isso, use sp_AddEscapeNoneToJobStepTokens procedimento armazenado. Você pode criar esse procedimento armazenado usando o seguinte script Transact-SQL.

Observação Verifique se a compilação do SQL Server 2005 SP1 que você instalar é uma compilação posterior ou compilação 2046. Além disso, você deve ser um membro da função de servidor fixo sysadmin para executar o script.
      -- This script is used to automatically edit SQL Agent job steps so that-- unescaped tokens are prefaced with the ESCAPE_NONE syntax that was added in-- SQL Server 2005 SP1.if (@@microsoftversion < 0x90007FE)BEGIN    RAISERROR('This script should only be run on at least SQL Server 2005 SP1.', 20, 127) WITH LOG    returnENDuse msdbgoif exists (select * from sys.objects where name = N'fn_PrefaceTokensWithEscapeNone' and type = 'FN')    drop function fn_PrefaceTokensWithEscapeNonego-- This function manipulates @commands so that all bare tokens-- are prefaced with ESCAPE_NONE.create function fn_PrefaceTokensWithEscapeNone(@commands nvarchar(max)) RETURNS nvarchar(max)ASBEGIN    if (@commands IS NULL)    BEGIN        return @commands    END    -- In order to let this script run under SQLCMD mode, we define    -- the special "$(" variable start string by concatenation so that    -- sqlcmd mode does not think that we are defining one of its variables.    declare @strVariableStart nchar(2)    select @strVariableStart = N'$' + N'('    declare @idxTokenStart int    select @idxTokenStart = CHARINDEX(@strVariableStart, @commands)    while (@idxTokenStart != 0 and @idxTokenStart is not null)    BEGIN        declare @idxCloseParen int        select @idxCloseParen = CHARINDEX(N')', SUBSTRING(@commands, @idxTokenStart, LEN(@commands)))        -- Error checking. If there is no close parenthesis, return.        if (0 = @idxCloseParen)        BEGIN            return @commands        END        -- Deduce the token variable.        declare @tokenLen int        select @tokenLen = @idxCloseParen - LEN(@strVariableStart) - 1        declare @token nvarchar(max)        select @token = SUBSTRING(@commands, @idxTokenStart + LEN(@strVariableStart), @tokenLen)        -- Verify if @token contains a mis-matched number of open and        -- close parens. This behavior could happen if invalid syntax is        -- in a comment block. If so, skip to the next token.        declare @idx int        declare @cOpenParens int        declare @cCloseParens int        select @cOpenParens = 0        select @idx = CHARINDEX(N'(', @token);        while (@idx != 0)        BEGIN            select @cOpenParens = @cOpenParens + 1            select @idx = CHARINDEX(N'(', @token, @idx + 1);        END        select @cCloseParens = 0        select @idx = CHARINDEX(N')', @token);        while (@idx != 0)        BEGIN            select @cCloseParens = @cCloseParens + 1            select @idx = CHARINDEX(N')', @token, @idx + 1);        END        -- Special case for the WMI token.        if (N'WMI(' = SUBSTRING(@token, 1, LEN(N'WMI(')))        BEGIN                select @cOpenParens = @cOpenParens - 1        END        if ((@cOpenParens = @cCloseParens) and            (N'ESCAPE_NONE(' != SUBSTRING(@token, 1, LEN(N'ESCAPE_NONE('))) and            (N'ESCAPE_SQUOTE(' != SUBSTRING(@token, 1, LEN(N'ESCAPE_SQUOTE('))) and            (N'ESCAPE_DQUOTE(' != SUBSTRING(@token, 1, LEN(N'ESCAPE_DQUOTE('))) and            (N'ESCAPE_RBRACKET(' != SUBSTRING(@token, 1, LEN(N'ESCAPE_RBRACKET('))))        BEGIN            select @commands = STUFF(@commands, @idxTokenStart + LEN(@strVariableStart), @tokenLen, N'ESCAPE_NONE(' + @token + N')')        END        select @idxTokenStart = CHARINDEX(@strVariableStart, @commands, @idxTokenStart + 1)    END    return @commandsENDgoif exists (select * from sys.objects where name = N'sp_AddEscapeNoneToJobStepTokens' and type = 'P')    drop procedure sp_AddEscapeNoneToJobStepTokensgo-- This procedure allows you to update jobs so that bare tokens-- are prefaced with ESCAPE_NONE. By default, all jobs are updated.-- You can optionally specify @job_name, @job_id, or @owner_name-- to limit the jobs that will be affected.CREATE PROCEDURE sp_AddEscapeNoneToJobStepTokens(    @job_name nvarchar(128) = null,    @job_id uniqueidentifier = null,    @owner_name nvarchar(256) = null)AS  -- Find the jobs to update. These jobs must match all of the input  -- criteria, unless all of the inputs are null. In this case,   -- examine all jobs.  The jobs must also be jobs created locally,  -- such as sysjobs.originating_server_id = 0. These jobs should not be a job that we run  -- because another server told us to.  Furthermore, if the job  -- is local but it is meant to be run on a target server, we send an  -- update for the job.  declare @jobsToUpdate TABLE (job_id uniqueidentifier not null)    insert into @jobsToUpdate      select job_id      from sysjobs      where originating_server_id = 0 -- local jobs      and ((COALESCE(@job_name, sysjobs.name) = sysjobs.name) and           (COALESCE(@job_id, sysjobs.job_id) = sysjobs.job_id) and           (COALESCE(@owner_name, suser_sname(sysjobs.owner_sid)) = suser_sname(sysjobs.owner_sid)))    -- Now find the job steps to update, creating the new command by using  -- fn_PrefaceTokensWithEscapeNone.  declare @jobStepsToUpdate TABLE (job_id uniqueidentifier not null,                                    step_id int not null,                                    command_old nvarchar(max) null,                                    command_new nvarchar(max) null,                                   output_file_old nvarchar(max) null,                                    output_file_new nvarchar(max) null)    insert into @jobStepsToUpdate  (job_id, step_id, command_old, command_new, output_file_old, output_file_new)      select job_id, step_id, command, dbo.fn_PrefaceTokensWithEscapeNone(command), output_file_name, dbo.fn_PrefaceTokensWithEscapeNone(output_file_name)      from sysjobsteps      where sysjobsteps.job_id =       (select job_id        from @jobsToUpdate        where job_id = sysjobsteps.job_id)    -- Now we update the actual job step commands. We do this first before  -- we push out the updated jobs to the target servers so the  -- target servers actually get the updated version.  declare @updated_job_id uniqueidentifier  declare @updated_job_step_id int  declare @updated_job_step_command nvarchar(max)  declare @updated_job_step_output_file nvarchar(max)    declare job_steps_cursor CURSOR FOR      select job_id, step_id, command_new, output_file_new      from @jobStepsToUpdate      order by job_id, step_id    OPEN job_steps_cursor  FETCH NEXT from job_steps_cursor into @updated_job_id, @updated_job_step_id, @updated_job_step_command, @updated_job_step_output_file  WHILE (@@FETCH_STATUS <> -1)  BEGIN      IF (@@FETCH_STATUS <> -2)      BEGIN          EXEC sp_update_jobstep @job_id = @updated_job_id, @step_id = @updated_job_step_id, @command = @updated_job_step_command, @output_file_name = @updated_job_step_output_file      END      FETCH NEXT from job_steps_cursor into @updated_job_id, @updated_job_step_id, @updated_job_step_command, @updated_job_step_output_file  END    CLOSE job_steps_cursor  DEALLOCATE job_steps_cursor      -- For multiserver jobs, call the sp_post_msx_operation stored procedure to update  -- all the target servers. Note that the sp_post_msx_operation stored procedure is safe  -- to call because it verifies whether the job is really a multiserver job.  declare jobs_cursor CURSOR FOR      select job_id      from @jobsToUpdate    OPEN jobs_cursor  FETCH NEXT from jobs_cursor into @updated_job_id  WHILE (@@FETCH_STATUS <> -1)  BEGIN      IF (@@FETCH_STATUS <> -2)      BEGIN          EXEC sp_post_msx_operation @operation = 'UPDATE', @job_id = @updated_job_id      END      FETCH NEXT from jobs_cursor into @updated_job_id  END    CLOSE jobs_cursor  DEALLOCATE jobs_cursor  -- List the jobs that we ran on, including the previous command  -- text. We list all of the job steps, even the ones that we did not  -- update. Otherwise, a jumble of job steps from  -- different jobs run together and the output is not  -- useful.  select N'Warning - Jobs Updated' = N'The following job steps and job output file names were analyzed and potentially updated to add the ESCAPE_NONE macro before any job tokens that were not already escaped. Please review the modified job steps and replace ESCAPE_NONE with the correct escape macro.'    select suser_sname(jobs.owner_sid) as N'Job owner',          jobs.name as N'Job name',          jobs.job_id,          jobStepsUpdated.step_id,          N'Modified' = CASE WHEN jobStepsUpdated.command_new != jobStepsUpdated.command_old or jobStepsUpdated.output_file_new != jobStepsUpdated.output_file_old THEN 1 ELSE 0 END,         N'Command' = jobStepsUpdated.command_new,          N'Previous Command' = jobStepsUpdated.command_old,          N'Output file' = jobStepsUpdated.output_file_new,          N'Previous Output file' = jobStepsUpdated.output_file_old      from sysjobs as jobs, @jobsToUpdate as jobsUpdated, @jobStepsToUpdate as jobStepsUpdated      where jobsUpdated.job_id = jobs.job_id and jobsUpdated.job_id = jobStepsUpdated.job_id      order by 'Job name', jobStepsUpdated.step_idgo
Depois de executar o script, o procedimento sp_AddEscapeNoneToJobStepTokens armazenado é criado. Por padrão, você irá atualizar todos os trabalhos, se você executar esse procedimento armazenado sem quaisquer parâmetros. Se você desejar atualizar somente trabalhos específicos, você deve especificar valores não nulos de pelo menos um dos três parâmetros a seguir:
  • @ job_name
  • @ job_id
  • @ owner_name
Por exemplo, você pode usar a seguinte sintaxe:
  • atualizar todos os trabalhos:
    EXEC sp_AddEscapeNoneToJobStepTokens
  • atualizar um trabalho especificando o nome do trabalho:
    EXEC sp_AddEscapeNoneToJobStepTokens 'MyJob'
  • Atualizar trabalhos que são de propriedade o mesmo proprietário:
    EXEC sp_AddEscapeNoneToJobStepTokens null,null,'JobOwner'
Esse script adiciona a macro ESCAPE_NONE para todas as etapas de trabalho que contêm símbolos. Após executar esse script, recomendamos que você examine seus etapas de trabalho que usam tokens assim que possível. Em seguida, substitua a macro ESCAPE_NONE um as macros de escape é apropriada para o contexto de etapa do trabalho.

Observação Se você estiver trabalhando em um ambiente de servidor (TSX) de destino e o servidor mestre (MSX), você deve executar esse script no MSX e o TSX para garantir que os trabalhos mestres no TSX estão atualizados corretamente.

Para obter mais informações sobre como atualizar trabalhos para usar a nova sintaxe e como usar macros de escape para ativar substituição de token nas etapas de trabalho do SQL Server Agent, consulte o tópico "Usando tokens em etapas do trabalho" no SQL Server 2005 Books Online (abril de 2006) ou versões posteriores do SQL Server 2005 Books Online.
Situação
A Microsoft confirmou que este é um problema nos produtos da Microsoft listados na seção "Aplica-se a".
Referências
Para obter mais informações sobre como usar tokens nas etapas de trabalho, visite o seguinte site da Web Microsoft Developer Network (MSDN):

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 915845 - Última Revisão: 05/24/2006 16:37:19 - Revisão: 2.1

Microsoft SQL Server 2005 Standard Edition, Microsoft SQL Server 2005 Workgroup Edition, Microsoft SQL Server 2005 Enterprise Edition

  • kbmt kbsql2005presp1fix kbprb kbexpertiseadvanced kbtshoot KB915845 KbMtpt
Comentários
xxxx-xxxx-4xxx-Rxxx-xxxxxxxxxxxx".replace(/x/g, function () { return Math.floor(Math.random() * 16).toString(16); })).replace("R", (8 | Math.floor(Math.random() * 3)).toString(16)); var m = document.createElement("meta"); m.content = guid; m.name = "ms.dqid"; document.getElementsByTagName("head")[0].appendChild(m);