Parte do código do nosso aplicativo converte os tipos de dados BINARY
para fins de hash. Por exemplo, convertemos BIGINT
valores para BINARY(8)
. A documentação avisa que as conversões podem mudar entre as versões do SQL Server:
Não há garantia de que as conversões entre qualquer tipo de dados e os tipos de dados binários sejam as mesmas entre as versões do SQL Server.
Como defesa contra isso, sempre que começamos a oferecer suporte a uma nova versão do SQL Server, tentamos executar testes para validar se todas as nossas conversões ainda são válidas. Para algo como BIGINT
, verificamos o comprimento do valor convertido para os valores mínimo e máximo permitidos BIGINT
. Esperamos que isso signifique que saberíamos se, por exemplo, o SQL Server 2019 começou a exigir BINARY(9)
o ajuste de todos os valores possíveis de BIGINT
.
Como podemos fazer esse tipo de análise para FLOAT(53)
? No momento, pensamos que todos os valores possíveis são mapeados para valores únicos que se encaixam em um BINARY(8)
, mas não sei como validar isso. Isso pode não ser tão simples quanto apenas verificar o número de bytes necessários para o tipo de dados. Por exemplo, o TIME
tipo de dados requer 5 bytes para armazenamento, mas deve ser convertido em a BINARY(6)
para evitar erros. Talvez isso seja irrelevante, mas também me deixa nervoso por BINARY
não poder ser convertido novamente para FLOAT
. Admito que posso estar pensando demais no problema, então aceito desafios de enquadramento como respostas.
Como posso escrever código para validar que todas as entradas possíveis para FLOAT(53)
não estourem a BINARY(8)
e que dois FLOAT(53)
valores diferentes não sejam convertidos no mesmo BINARY(8)
valor?
O tamanho, em bytes, de BIGINT e FLOAT(53) está documentado. Seria uma mudança importante tornar qualquer um deles não conversível para BINARY(8).
A documentação que você cita é sobre os detalhes da conversão, que não estão documentados e estão sujeitos a alterações. Por exemplo, o layout de bytes de um float(53) nesta conversão pode mudar. Portanto, se você converter um float para binary(8), armazenar o binary(8) em uma tabela, atualizar o SQL Server e converter o binary(8) de volta para float, talvez não obtenha o mesmo valor.
Esses tipos específicos têm layouts de bytes bem conhecidos. BIGINT é um pequeno inteiro endian de 8 bytes e float(53) é um número de ponto flutuante de precisão dupla padrão. E seria bastante surpreendente se um deles mudasse. Mas outros tipos, especialmente os baseados em CLR, realmente podem alterar seu layout entre as versões.