Al momento sei offline in attesa che la connessione Internet venga ristabilita

I processi di Agente SQL Server non riuscire quando i processi contengono passaggi di processo che utilizzano token dopo l'installazione SQL Server 2005 Service Pack 1

Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell’utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell’utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.

Clicca qui per visualizzare la versione originale in inglese dell’articolo: 915845
Bug #: 426808 (SQLBUDT)
Sintomi
Dopo l'installazione di SQL Server 2005 Service Pack 1 (SP1), si verificherà il problema seguente:
  • I processi di Agente SQL Server esito negativo quando i processi contengono passaggi di processo che consente di utilizzano token.
  • È visualizzato il seguente messaggio di errore:
    Il passaggio di processo contiene uno o più token. Per SQL Server 2005 Service Pack 1 o versioni successive, è necessario aggiornare tutti i passaggi di processo con token con una macro prima di eseguita il processo.
Nota Questo problema si verifica con generazione 2046 o versioni successive versioni di SQL Server 2005.
Cause
In SQL Server 2005 SP1 è cambiato la sintassi di Agente SQL Server del token di passaggio del processo. A questo punto, è necessario includere una macro di escape con tutti i token vengono utilizzati nei passaggi di processo. Se non si include una macro di escape, non saranno i passaggi di processo. Nella tabella seguente sono elencate le macro di escape.
Macro di escapeDescrizione
$ (ESCAPE_SQUOTE (TokenName))Questa macro esegue l'escape apostrofi (') nella stringa di token di sostituzione. La macro sostituisce un apostrofo con due apostrofi.
$ (ESCAPE_DQUOTE (TokenName))Questa macro esegue l'escape virgolette ("") nella stringa di token di sostituzione. La macro sostituisce un segno di virgolette con due virgolette.
$ (ESCAPE_RBRACKET (TokenName))Questa macro esegue l'escape tra parentesi destra (]) nella stringa di token di sostituzione. La macro sostituisce una parentesi quadra chiusa con due parentesi destra.
$ (ESCAPE_NONE (TokenName))La macro sostituisce un token senza i caratteri nella stringa di escape. Questa macro viene fornita per supportare la compatibilità con le versioni precedenti in ambienti in cui le stringhe di sostituzione di token sono previsti solo da utenti attendibili.
Ad esempio, un passaggio di processo può contenere la seguente istruzione Transact-SQL che utilizza il token DBN di A :
CREATE DATABASE [$(A-DBN)]
in questo esempio, è necessario aggiornare la sintassi di token alla seguente sintassi:
CREATE DATABASE [$(ESCAPE_RBRACKET(A-DBN))]
questa modifica è diverso dal comportamento precedente di SQL Server 2005, le macro di escape non erano necessarie.
Risoluzione
Per risolvere questo problema, eseguire l'aggiornamento tutti o solo i processi specifici che utilizzano token alla nuova sintassi token. Per eseguire questa operazione, utilizzare lo sp_AddEscapeNoneToJobStepTokens stored procedure. È possibile creare questa stored procedure utilizzando lo script Transact-SQL seguente.

Nota Assicurarsi che la build di SQL Server 2005 SP1 è installare sia generazione 2046 o di una build successiva. Inoltre, è necessario essere un membro del ruolo server fisso sysadmin per l'esecuzione di 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
Dopo aver eseguito lo script, viene creata la procedura sp_AddEscapeNoneToJobStepTokens memorizzati. Per impostazione predefinita, tutti i processi verrà aggiornata se si esegue questa stored procedure senza parametri. Se si desidera aggiornare solo i processi specifici, è necessario specificare i valori non null per almeno uno dei tre parametri seguenti:
  • @ job_name
  • @ job_id
  • @ nome_proprietario
Ad esempio, è possibile utilizzare la seguente sintassi:
  • tutti i processi di aggiornamento:
    EXEC sp_AddEscapeNoneToJobStepTokens
  • per aggiornare un processo, che specifica il nome di processo:
    EXEC sp_AddEscapeNoneToJobStepTokens 'MyJob'
  • aggiornamento processi che appartengono allo stesso proprietario:
    EXEC sp_AddEscapeNoneToJobStepTokens null,null,'JobOwner'
Questo script aggiunge la macro ESCAPE_NONE tutti i passaggi processo che contengono il token. Dopo aver eseguito questo script, si consiglia di esaminare i passaggi di processo che utilizzano token nel minor tempo possibile. Sostituire quindi la macro ESCAPE_NONE con una delle altre macro escape appropriato per il contesto del passaggio di processo.

Nota Se si lavora in un server master (MSX) e l'ambiente di destinazione (TSX) del server, è necessario eseguire questo script sia nel server MSX che server TSX per assicurarsi che i processi master nel server TSX vengono aggiornati correttamente.

Per ulteriori informazioni su come aggiornare i processi a utilizzare la nuova sintassi e su come utilizzare le macro di escape per attivare la sostituzione di token nei passaggi del processo di Agente SQL Server, vedere l'argomento "Utilizzo token in passaggi di processo" in linea di SQL Server 2005 documentazione (aprile 2006) o versioni successive di documentazione in linea di SQL Server 2005 (informazioni in lingua inglese).
Status
Microsoft ha confermato che questo problema riguarda i prodotti sono elencati nella sezione "Si applica a".
Riferimenti
Per ulteriori informazioni sull'utilizzo di token nei passaggi di processo, visitare il seguente sito Web MSDN (informazioni in lingua inglese):

Avviso: questo articolo è stato tradotto automaticamente

Proprietà

ID articolo: 915845 - Ultima revisione: 05/24/2006 16:37:19 - Revisione: 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 KbMtit
Feedback
; " src="https://c1.microsoft.com/c.gif?DI=4050&did=1&t=">