OlĂ¡ pessoal,
Boa noite!
No post de hoje vou falar sobre um erro nĂ£o muito comum que ocorre no SQL Server ao tentar executar queries utilizando Linked Server ou instruções entre servidores (Ex: OPENROWSET, OPENQUERY, etc) e o SQL Server nos retorna a seguinte mensagem:
Msg 7405, Level 16, State 1, Line 45
Heterogeneous queries require the ANSI_NULLS and ANSI_WARNINGS options to be set for the connection. This ensures consistent query semantics. Enable these options and then reissue your query.
A primeira vez que vi esse erro, foi quando meu colega Henrique Mauri, o cara que mais estĂ¡ me dando ideias de posts ultimamente, tentou criar uma sequence e utilizĂ¡-la em uma funĂ§Ă£o escalar que era chamada a partir de uma stored procedure dentro de uma aplicaĂ§Ă£o escrita em C# e se deparou com essa mensagem de erro.
Esse problema ocorre especialmente quando se desativa manualmente as instruções ANSI_NULLS e ANSI_WARNINGS antes de utilizar um linked server no SQL Server. Vamos entender o porque isso acontece e como resolver.
Por quĂª utilizar ANSI_NULLS e ANSI_WARNINGS?
Antes de mais nada, preciso deixar claro que o problema relatado neste post sĂ³ ocorre quando pelo menos uma dessas duas configurações estĂ¡ desabilitada (OFF). JĂ¡ falei sobre as duas no meu post Os comandos SET do SQL Server. O padrĂ£o do SQL Server Ă© que elas esteja ativadas (ON), mas muita gente acaba desabilitando para evitar alertas ao utilizar de forma ERRADA algumas queries no banco de dados.
Eu recomendo fortemente que vocĂª NĂƒO desative o ANSI_NULLS e ANSI_WARNINGS nas suas rotinas. Na verdade, nem me lembro quando foi a Ăºltima vez precisei alterar o comportamento padrĂ£o de uma query utilizando comandos SET (a nĂ£o ser utilizando SET LANGUAGE e SET DATEFORMAT).
Segundo o prĂ³prio site da Microsoft, em uma versĂ£o futura do SQL Server, ANSI_NULLS sempre estarĂ¡ ON e quaisquer aplicativos que definam explicitamente a opĂ§Ă£o como OFF gerarĂ£o um erro. Evite usar esse recurso em novos trabalhos de desenvolvimento e planeje modificar os aplicativos que o utilizam atualmente.
Simulando o problema
Para simular esse problema, vou disponibilizar abaixo um script que vai mostrar exatamente essa mensagem de erro. Lembrem de trocar o nome do LinkedServer pro nome da sua instĂ¢ncia SQL Server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
---------------------------------- -- CRIAĂ‡ĂƒO DO LINKED SERVER ---------------------------------- USE [master] GO DECLARE @instancia NVARCHAR(200) = N'127.0.0.1\SQL2014' IF ((SELECT COUNT(*) FROM sys.servers WHERE name = @instancia) > 0) EXEC master.dbo.sp_dropserver @server=@instancia, @droplogins='droplogins' EXEC master.dbo.sp_addlinkedserver @server = @instancia, @srvproduct=N'SQL Server' EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=@instancia,@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL ---------------------------------- -- CRIAĂ‡ĂƒO DA TABELA DE TESTES ---------------------------------- IF (OBJECT_ID('Testes.dbo.Teste') IS NOT NULL) DROP TABLE Testes.dbo.Teste SELECT 12456.74 AS Valor, 'Teste 1' AS Tipo INTO Testes.dbo.Teste UNION SELECT 1314.00, 'Teste 2' UNION SELECT 745.99, 'Teste 2' UNION SELECT 1587.90, 'Teste 1' UNION SELECT 100, NULL UNION SELECT NULL, NULL ---------------------------------- -- SIMULAĂ‡ĂƒO DO ERRO ---------------------------------- SET ANSI_NULLS OFF GO SELECT SUM(Valor), Tipo FROM [127.0.0.1\SQL2014].Testes.dbo.Teste GROUP BY Tipo |
Resolvendo o problema
Pessoal, a soluĂ§Ă£o desse problema Ă© extremamente simples e jĂ¡ estĂ¡ claro pela mensagem de erro e por tudo o que eu jĂ¡ falei no post. Basta ativar os parĂ¢metros SET ANSI_WARNINGS E SET ANSI_NULLS.
Se vocĂª jĂ¡ fez isso e continua recebendo essa mensagem de erro, procure todo o seu cĂ³digo-fonte, porque com certeza o problema Ă© esse. Veja se nĂ£o tem nenhuma SP sendo executada e que esteja desativando uma das duas opções ou algum cĂ³digo ad-hoc na sua aplicaĂ§Ă£o ou na sua camada de acesso a banco de dados. Verifique tambĂ©m o comando de criaĂ§Ă£o das Stored Procedures envolvidas, pois pode ser que no comando de CREATE/ALTER PROCEDURE essas opções tenham sido desativadas.
Espero que tenham gostado do post.
AtĂ© a prĂ³xima!
Muito boa essa dica