Descobri que as consultas abaixo retornam resultados diferentes em dois bancos de dados de hiperescala do Azure que estão executando o mesmo nível de compatibilidade, as mesmas opções de conjunto etc.
IF CAST(ServerProperty('Edition') AS nvarchar(128)) = 'SQL Azure' BEGIN
SELECT 1
END
IF ServerProperty('Edition') = 'SQL Azure' BEGIN
SELECT 2
END
IF 'SQL Azure' = ServerProperty('Edition') BEGIN
SELECT 3
END
Em um banco de dados, ele retorna apenas 1, em outro banco de dados retorna 1,2 e 3.
Eu investiguei a causa raiz e parece ser causada por diferentes agrupamentos dos bancos de dados.
Para as seguintes consultas:
SELECT SQL_VARIANT_PROPERTY(ServerProperty('Edition'), 'Collation')
SELECT name, collation_name, compatibility_level FROM sys.databases
O banco de dados que retorna apenas uma linha, o resultado é:
-----------------------------
SQL_Latin1_General_CP1_CI_AS
name collation_name compatibility_level
------------ -------------------------------- -------------------
master SQL_Latin1_General_CP1_CI_AS 140
my_database SQL_Latin1_General_CP850_CI_AS 150
E o resultado do banco de dados que retorna 1,2,3 é:
-----------------------------
SQL_Latin1_General_CP1_CI_AS
name collation_name compatibility_level
------------ -------------------------------- -------------------
master SQL_Latin1_General_CP1_CI_AS 140
my_database SQL_Latin1_General_CP1_CI_AS 150
Portanto, a comparação simples sem o elenco está comparando sql_variant
com varchar
(não há diferença quando eu uso N'SQL Azure'
) onde o subjacente nvarchar
do sql_variant
tem em um caso um agrupamento diferente do banco de dados que eu consulto e, em outro caso, é correspondente.
Em primeiro lugar, eu diria que a comparação de duas strings com agrupamento diferente falharia como falha quando você tenta unir duas colunas com agrupamento diferente, mas aparentemente não é o caso aqui.
De qualquer forma, qual é a melhor maneira de comparar com segurança a saída de uma função que pode estar sql_variant
com um varchar
?