[Atualização: esta pergunta descreve um bug que foi corrigido na atualização cumulativa 5 para SQL Server 2019. ]
Considere o seguinte exemplo de reprodução ( fiddle ):
CREATE FUNCTION dbo.Repro (@myYear int)
RETURNS datetime
AS
BEGIN
IF @myYear <> 1990
BEGIN
RETURN NULL
END
DECLARE @firstOfYear datetime;
SET @firstOfYear = DATEFROMPARTS(@myYear, 1, 1);
IF DATEDIFF(day, @firstOfYear, @firstOfYear) <> 0
BEGIN
RETURN NULL
END
RETURN @firstOfYear
END
SELECT dbo.Repro(0);
Obviamente, essa função deve retornar o primeiro de janeiro de 1990 se a entrada for 1990
, e NULL
caso contrário. Sim, eu sei que DATEDIFF(day, @firstOfYear, @firstOfYear) <> 0
é uma operação sem sentido. Este é um mcve para demonstrar um possível bug, não o código de produção.
Agora vamos executar SELECT dbo.Repro(0)
no SQL Server 2017 e SQL Server 2019.
Resultado esperado : NULL
.
Resultado real no SQL Server 2017 :NULL
Resultado real no SQL Server 2019 :
Msg 289 Nível 16 Estado 1 Linha 1
Não é possível construir o tipo de dados data, alguns dos argumentos possuem valores que não são válidos.
Aparentemente, o SQL Server 2019 executa parte do código abaixo da cláusula de guarda inicial ( IF @myYear <> 1990
), mesmo que não devesse.
Minhas perguntas:
- Esse comportamento é esperado ou encontrei um bug no SQL Server 2019?
- Se esse for o comportamento esperado, como escrever corretamente uma cláusula de guarda validando os parâmetros de entrada?