Eu tenho uma coluna VARCHAR(MAX) em uma tabela que pode armazenar dados em vários formatos diferentes, incluindo o formato GUID. Tentei o seguinte código ao ingressar em uma coluna UNIQUEIDENTIFIER em outra tabela:
TRY_CAST(b.val AS uniqueidentifier) = a.guid_col
Estou tendo o erro a seguir:
Msg 8152, Nível 16, Estado 10, Linha 73
String ou dados binários seriam truncados.
A documentação para TRY_CAST diz que erros podem ser lançados em algumas circunstâncias:
No entanto, se você solicitar uma conversão explicitamente não permitida, TRY_CAST falhará com um erro.
No entanto, uma conversão de VARCHAR para UNIQUEIDENTIFIER é permitida pelo SQL Server:
Consegui encontrar um valor de exemplo que gera o erro. O valor é bastante longo, então incluí nele um violino . Comentários úteis forneceram uma reprodução mais simples do problema:
DECLARE @s VARCHAR(MAX) = REPLICATE(CAST('A' AS VARCHAR(MAX)), 8001);
SELECT TRY_CAST(@s AS UNIQUEIDENTIFIER);
Por que TRY_CAST lança um erro em vez de retornar um valor NULL ao tentar converter determinados valores VARCHAR em UNIQUEIDENTIFIER?
A tabela de conversão na documentação não faz distinção entre
varchar
evarchar(max)
, embora outra seção daCAST
documentaçãoCONVERT
diga:Também relevante, de char e varchar :
Quando você fornece um
varchar(max)
para asTRY_*
funções com um tipo não máximo como destino, é feita uma tentativa de converter o valor grande em uma string não máxima. Se isso for bem-sucedido, tudo bem. Caso contrário, você obtém um "String ou dados binários seriam truncados". erro porque a string máxima não caberia. Isso vai contra a documentação acima, que afirma que o truncamento ocorre.Minha própria experiência é que
max
os tipos de dados às vezes têm um comportamento que não segue o gráfico de conversão ou a documentação detalhada.Esse comportamento não é específico para
uniqueidentifier
, a demonstração na pergunta falhará com outros tipos comobigint
oudate
.Minha lembrança é que
TRY_*
funcionará de forma confiável para tipos compatíveis comsql_variant
(o que exclui tipos grandes). Você também pode usar as funções try para converter entre os tipos máximos, mas nem sempre de máximo para não máximo.Não é ideal do ponto de vista da experiência do usuário. Não sei se é um erro de documentação ou comportamento não intencional.
Como solução alternativa, você pode converter o texto LOB no comprimento da representação de string de um GUID antes de tentar a conversão try:
Item de feedback existente da Microsoft .
Perguntas e respostas relacionadas: