NoLock – Remote table-valued function calls

Olá pessoas. Estou participando de uma migração e achei interessante compartilhar um caso com vocês.

O Post é bem pequenino somente a título de curiosidade mesmo.

Nessa migração estamos retirando as bases de dados do ambiente de produção SQL Server 2008 R2 com modo de compatibilidade 80 para SQL Server 2014 com modo de compatibilidade 120.

A maior dificuldade dessa migração é sair do modo de compatibilidade 80, pois a partir dele muita sintaxe deixou de funcionar como o * = / = * substituído pelo Left join / Right Join e a sintaxe do Raiserror sendo exigido colocar os parâmetros entre parênteses, porém uma coisa que deixou a equipe mais “encucada”  foi o NoLock .

Sabemos que os desenvolvedores quase nunca usam o NoLock, né? (sarcasmo). Então tivemos uma amostra legal do erro.

Na documentação do SQL Server 2016 está dizendo que em versões futuras não será mais permitido a utilização de Hints sem a clausula “With”, porém EM VERSÕES FUTURAS, ou seja, ainda conseguimos usar o NoLock sem o With.

hintssqlserver

Porém quando executamos uma consulta via linked server sem a clausula with, é retornado o seguinte erro:

SELECT *
FROM [sqlh110].master.sys.databases (NOLOCK)

Msg 4122, Level 16, State 1, Line 2
Remote table-valued function calls are not allowed.

Obs.: A consulta foi realizada em um SQL Server 2014 (SP2).

Agora vocês pensam: “O quê é que tem a ver erro de Remote table-value function com o NoLock? “.

Tudo indica que o parse do SQL Server entende aqui que ao colocar o NoLock entre parênteses (NOLOCK) na verdade está chamando uma função remotamente e que não é uma Hint. Vi essa explicação no seguinte link:

(http://stackoverflow.com/questions/17242733/why-is-with-required-when-using-nolock-on-a-remote-table-call)

Podemos provar isso com a seguinte consulta:

SELECT *
FROM [sqlh110].master.sys.databases NOLOCK

resultadoselectnolock

Ao retirar o parênteses a consulta retorna o resultado normalmente, mesmo sem a clausula “With”.

Identificamos que para o código voltar a funcionar basta retirar os parênteses, porém já que o mesmo será editado para corrigir o erro recomendo que editem da forma “completa”, pois, como olhamos na documentação, isso será descontinuado, então não custa nada sempre que forem utilizar a Hint “NoLock”, que a mesma seja precedida pela clausula “With”, evitando assim, erros em versões futuras.

Editado em 28/12/2016

Conforme observado pelo Reginaldo Silva o nolock sem os parênteses funciona, pois na verdade o SQL Server entende que a palavra “NoLock” é um alias e não uma Hint para realizar a leitura suja, ou seja, para consertar de fato o erro citado no post é colocando o with antes do (nolock).

Anúncios

9 pensamentos sobre “NoLock – Remote table-valued function calls

  1. Bom dia Nane.

    Legal o Post, bem interessante, nunca peguei esse erro em especifico.

    Porém tome cuidado, se não me engano esse comportamento mudou a partir do 2008 R2, não sei dizer a versão exata, mas quando se usa NOLOCK sem o () ele vira um alias para a tabela e perde sua utilidade, da uma olhada no plano de execução você vai ver que o alias da tabela vai estar como ‘Nolock’ e se precisar fazer leitura suja não vai conseguir devido a engine não entender mais isso como um hint, então se nesse caso o () não funciona sem o WITH, provavelmente o Nolock esta apenas como alias.

    Atenciosamente
    Reginaldo Silva

    • Bem observado Reginaldo.

      Após o seu comentário realizei os testes e realmente a leitura suja não é realizada quando colocado somente o NOLOCK. Vou editar o post com essa informação.

      Obrigada pelo comentário.

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