Estou usando o SQL Server 2019 e acabei de encontrar um comportamento estranho. A pesquisa não me levou a lugar nenhum.
Alguém pode explicar esse comportamento?
SET QUOTED_IDENTIFIER ON;
if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off';
BEGIN TRY
if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
END TRY
BEGIN CATCH
if ((256 & @@options) = 256) print '3- quoted_identifier is on' else print '3- quoted_identifier is off';
-- SET QUOTED_IDENTIFIER OFF
-- if ((256 & @@options) = 256) print '4- quoted_identifier is on' else print '4- quoted_identifier is off';
END CATCH
Devoluções:
1- quoted_identifier is on
2- quoted_identifier is on
mas o seguinte código:
SET QUOTED_IDENTIFIER ON;
if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off';
BEGIN TRY
if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
END TRY
BEGIN CATCH
if ((256 & @@options) = 256) print '3- quoted_identifier is on' else print '3- quoted_identifier is off';
SET QUOTED_IDENTIFIER OFF
if ((256 & @@options) = 256) print '4- quoted_identifier is on' else print '4- quoted_identifier is off';
END CATCH
Devoluções:
1- quoted_identifier is off
2- quoted_identifier is off
Mesmo que não vá para a captura!!! Eu devo estar esquecendo alguma coisa.
Consegui até simplificar o código para o mais simples:
SET QUOTED_IDENTIFIER ON;
if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off';
SET QUOTED_IDENTIFIER OFF
if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
Resultados:
1- quoted_identifier is off
2- quoted_identifier is off
Eu tenho algum código que usa FOR XML
, o que exige que eu defina o identificador citado como LIGADO, mas preciso colocá-lo novamente em DESLIGADO, não importa se a parte XML for bem-sucedida ou falhar. Como você faria isso?
Meus testes mostram que, se eu colocar o SET QUOTED_IDENTIFIER
to off no CATCH
, a inserção falha ao dizer que meu identificador citado não está definido corretamente, embora esteja definido no início do TRY
to ON
.
Isso é por design:
O comportamento de
QUOTED_IDENTIFIER
é, portanto, dependente da análise do lote, não da execução. O padrão no início da análise do lote vem das configurações de conexão atuais.@@OPTIONS
mostra apenas o padrão atual, que seria usado se um lote fosse analisado. É por isso que o SSMS sempre colocaSET
em um lote separado.A execução de
SET
não é relevante para o comportamento de@@OPTIONS
, exceto para alterar o padrão dos lotes posteriores.Você pode ver isso em ação em um db-fiddle
A resposta de Charlieface parece ter explicado adequadamente o motivo do comportamento que você descreveu ao usar
SET QUOTED_IDENTIFIER
, então vou deixar um método que você poderia usar se precisasse usá-lo dentro de um SP:Solução sugerida
Isole parte do seu lote em outro procedimento e chame-o daquele em que
QUOTED_IDENTIFIER
precisa serOFF
assim: db<>fiddle - execute no seu computador em 2 sessões diferentes, pois não consegui fazê-lo funcionar corretamente no dbfiddle.