Cuidado com casts em campos char/nchar/varchar/nvarchar

Há erros que nunca cometemos. Por exemplo, um overflow num int que nos faz pensar por que raio é que a coluna não foi logo definida como bigint. Ou um destes casos que quero mostrar agora. Porque nunca acontecem.

Sabemos que se tentarmos ultrapassar certos limites, o SQL Server nos avisa.

declare @i int = 1123234243333

Ou este

declare @b bigint = 1234567890123456789
select cast(@b as int)

Mas há outros…

declare @nvarchar50		nvarchar(50)
set @nvarchar50	   	=	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	
select @nvarchar50
Truncou implicitamente, e népia de aviso.

Vamos correr de novo para vermos os tamanhos reais em bytes e caracteres

declare @nvarchar50		nvarchar(50)
set @nvarchar50	   	=	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	
select @nvarchar50
select Data_Lenght = datalength(@nvarchar50)	
select Lenght = len(@nvarchar50) 
go

Sem dúvidas, temos 50 caracteres e 100 bytes.

Então quer dizer que não recebemos nenhum warning por existir truncation.

Se fizermos o mesmo com MAX…

declare @nvarcharmax		nvarchar(max)
set @nvarcharmax	   	=	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	
select @nvarcharmax
select Data_Lenght = datalength(@nvarcharmax)	
select Lenght = len(@nvarcharmax) 
go

Sem questões, ocupamos o espaço que necessitamos e não há truncation. Claro.

Agora imaginemos que declaramos uma variável nvarchar e nos esquecemos de colocar o tamanho…

declare @nvarchar nvarchar =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @nvarchar
select Data_Lenght = datalength(@nvarchar)	
select Lenght = len(@nvarchar) 
go

Ficamos apenas com o primeiro caractere, como se nota.

Mas se o erro acima é difícil de acontecer, imaginem que nos esquecemos de colocar o tamanho ao fazermos um cast. Este já tenho visto por aí…

declare @nvarchar255 nvarchar(255) =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @nvarchar255
select Data_Lenght = datalength(@nvarchar255)	
select Lenght = len(@nvarchar255) 
select CAST(@nvarchar255 as nvarchar)
go

Este caso é interessante, porque ficamos com 30 caracteres na nossa saída. Interessante e mais difícil de encontrar o “gato” mais tarde quando os nossos campos começarem a aparecer truncados…

Será que acontece apenas com nvarchar?

declare @varchar varchar =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @varchar
select Data_Lenght = datalength(@varchar)	
select Lenght = len(@varchar) 
go

declare @nchar nchar =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @nchar
select Data_Lenght = datalength(@nchar)	
select Lenght = len(@nchar) 
go

declare @char char =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @char
select Data_Lenght = datalength(@char)	
select Lenght = len(@char) 
go

Não, por omissão é sempre 1 caractere.

E nos casts?

declare @varchar255 varchar(255) =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @varchar255
select Data_Lenght = datalength(@varchar255)	
select Lenght = len(@varchar255) 
select CAST(@varchar255 as varchar)
go

declare @nchar255 nchar(255) =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @nchar255
select Data_Lenght = datalength(@nchar255)	
select Lenght = len(@nchar255) 
select CAST(@nchar255 as nchar)
go

declare @char255 char(255) =	'0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999'	 
select @char255
select Data_Lenght = datalength(@char255)	
select Lenght = len(@char255) 
select CAST(@char255 as char)
go

Igual. 30 caracteres sobram da nossa string de 100.

Façam aquilo que eu digo, e não aquilo que eu fiz. 🙂

Se virem campos de texto truncados contem os caracteres existentes e se forem 30 já sabem onde procurar.

Share

You may also like...

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *