Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
Depois de instalar o Microsoft SQL Server 2005 Service Pack 1 (SP1), poderá detectar o seguinte comportamento:
Tarefas do SQL Server Agent falham quando as tarefas contém passos de tarefa que utilizar tokens.
Receberá a seguinte mensagem de erro:
O passo de tarefa contém um ou mais tokens. Para o SQL Server 2005 Service Pack 1 ou versões posteriores, todos os passos de tarefa com tokens devem ser actualizados com uma macro antes da tarefa pode ser executado.
Nota Este problema ocorre com compilação 2046 ou posteriores versões do SQL Server 2005.
No SQL Server 2005 SP1, a sintaxe de token de passo do SQL Server Agent tarefa foi alterado. Agora, tem de incluir uma macro de escape com todos os tokens utilizados nos passos de tarefa. Se não incluir uma macro de escape, esses passos tarefa falhará. A tabela seguinte lista as macros de escape.
Reduzir esta tabelaExpandir esta tabela
Macro de escape
Descrição
$ (ESCAPE_SQUOTE (TokenName))
Esta macro escapa apóstrofes (') na cadeia de substituição de token. A macro substitui um apóstrofo com duas plicas.
$ (ESCAPE_DQUOTE (TokenName))
Esta macro escapa entre aspas (") na cadeia de substituição de token. A macro substitui uma aspa por duas aspas.
$ (ESCAPE_RBRACKET (TokenName))
Esta macro escapa parênteses direito (]) na cadeia de substituição de token. A macro substitui um parêntese recto direito com dois parênteses direito.
$ (ESCAPE_NONE (TokenName))
A macro substitui um token sem sair de todos os caracteres na cadeia. Esta macro é fornecida para suportar a compatibilidade com versões anteriores em ambientes onde cadeias de substituição token só são esperadas de utilizadores fidedignos.
Por exemplo, um passo de projecto pode conter a seguinte instrução de Transact-SQL que utiliza o token De DBN :
CREATE DATABASE [$(A-DBN)]
neste exemplo, terá de actualizar a sintaxe de token para a seguinte sintaxe:
CREATE DATABASE [$(ESCAPE_RBRACKET(A-DBN))]
esta alteração difere comportamento anterior do SQL Server 2005, onde a macros de escape não eram necessárias.
Para resolver este problema, actualize ou tudo ou apenas tarefas específicas que utilizam sinais para a nova sintaxe token. Para o fazer, utilize o procedimento sp_AddEscapeNoneToJobStepTokens armazenados. Pode criar este procedimento armazenado utilizando o seguinte script Transact-SQL.
Nota Certifique-se que a compilação de SQL Server 2005 SP1 instalar está compilação 2046 ou uma compilação posterior. Além disso, tem de ser um membro da função de servidor fixa 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
return
END
use msdb
go
if exists (select * from sys.objects where name = N'fn_PrefaceTokensWithEscapeNone' and type = 'FN')
drop function fn_PrefaceTokensWithEscapeNone
go
-- This function manipulates @commands so that all bare tokens
-- are prefaced with ESCAPE_NONE.
create function fn_PrefaceTokensWithEscapeNone(@commands nvarchar(max)) RETURNS nvarchar(max)
AS
BEGIN
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 @commands
END
go
if exists (select * from sys.objects where name = N'sp_AddEscapeNoneToJobStepTokens' and type = 'P')
drop procedure sp_AddEscapeNoneToJobStepTokens
go
-- 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_id
go
Depois de executar o script, o procedimento armazenado sp_AddEscapeNoneToJobStepTokens é criado. Por predefinição, irá actualizar todas as tarefas se executar este procedimento armazenado sem quaisquer parâmetros. Se pretender actualizar apenas tarefas específicas, tem de especificar valores não nulos para pelo menos uma das seguintes três parâmetros:
@ job_name
@ emprego_id
@ owner_name
Por exemplo, pode utilizar a seguinte sintaxe:
Actualizar todas as tarefas:
EXEC sp_AddEscapeNoneToJobStepTokens
actualizar uma tarefa, especificando o nome de tarefa:
EXEC sp_AddEscapeNoneToJobStepTokens 'MyJob'
actualizar tarefas que são propriedade do mesmo proprietário:
Este script adiciona a macro ESCAPE_NONE para todos os passos de tarefa que contêm tokens. Depois de executar este script, recomendamos que reveja os passos de trabalho que utilizam tokens assim que possível. Em seguida, substitua a macro ESCAPE_NONE das outras macros de escape apropriado para o contexto de passo de tarefa.
Nota Se estiver a trabalhar num ambiente de servidor (TSX) de destino e servidor principal (MSX), tem de executar este script a MSX tanto o TSX para garantir que projectos principais na TSX são correctamente actualizados.
Para obter mais informações sobre como actualizar tarefas para utilizar a nova sintaxe e como utilizar macros de escape para activar substituição token nos passos de tarefa do agente do SQL Server, consulte o tópico "Utilizando tokens de na tarefa passos" no SQL Server 2005 Books Online (Abril de 2006) ou versões posteriores do SQL Server 2005 Books Online.
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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 915845
(http://support.microsoft.com/kb/915845/en-us/
)
Qual foi o esforço que despendeu pessoalmente para utilizar este artigo?
Muito baixo
Baixo
Moderado
Elevado
Muito elevado
Diga-nos porquê e o que podemos fazer para melhorar estas informações
Obrigado! Os seus comentários são utilizados para ajudar-nos a melhorar o conteúdo do nosso suporte. Para obter mais opções de assistência, visite a Home Page de Ajuda e Suporte.