Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Correção da Msg 8117 “O tipo de dados do operando varchar é inválido para o operador de soma” no SQL Server


Se você estiver recebendo a mensagem de erro 8117 do SQL Server com a mensagem Operand data type varchar is invalid for sum operator , é porque você está passando o tipo de dados errado para um operador ou função.

Nesse caso, o erro indica que estamos passando uma string para o SUM() função. Tele SUM() função não opera em strings. Ele só funciona em tipos numéricos.

O mesmo erro (Msg 8117) também pode ocorrer em outros contextos – não se limita ao SUM() função.

Exemplo do erro


Aqui está um exemplo de código que produz o erro:
SELECT SUM(ProductName) 
FROM Products; 

Resultado:
Msg 8117, Level 16, State 1, Line 1Operand tipo de dados varchar é inválido para o operador de soma.

Nesse caso, estamos tentando adicionar o ProductName coluna.

Nesse caso, é muito provável que o ProductName coluna é um varchar coluna. Provavelmente temos a coluna errada.

Solução 1


Para corrigir esse erro, devemos primeiro verificar se temos a coluna correta. Se não tivermos a coluna correta, altere-a para a coluna correta:
SELECT SUM(Price) 
FROM Products; 

Espero que isso resolva o problema. Em outras palavras, esperamos que o Price coluna é numérica, como deveria ser.

Mas e se não for?

Solução 2


Em alguns casos, você pode descobrir que tem a coluna correta, mas essa coluna usa um tipo de dados inadequado. Por exemplo, suponha que nosso Price coluna foi realmente definida como um varchar coluna.

Nesse caso, teríamos o mesmo erro:
SELECT SUM(Price) 
FROM Products; 

Resultado:
Msg 8117, Level 16, State 1, Line 1Operand tipo de dados varchar é inválido para o operador de soma.

À primeira vista, nada parece estar errado com esta afirmação. Tudo o que estamos fazendo é obter um total dos valores no Price coluna. Este é um exemplo perfeito do que o SUM() função foi projetada para fazer.

Claro, a suposição aqui é que o Price coluna é numérica. Mas de acordo com a mensagem de erro, não é numérico – é um varchar .

Vamos verificar o tipo de dados da coluna:
SELECT
    DATA_TYPE, 
    CHARACTER_MAXIMUM_LENGTH AS MAX_LENGTH, 
    CHARACTER_OCTET_LENGTH AS OCTET_LENGTH 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'Products' 
AND COLUMN_NAME = 'Price'; 

Resultado:
+-------------+--------------+----------------+ | DATA_TYPE | MAX_LENGTH | OCTET_LENGTH ||-------------+--------------+----------------|| varchar | 255 | 255 |+-------------+--------------+----------------+ 
Como suspeito, a coluna é do tipo varchar .

Neste caso, temos duas opções; altere o tipo da coluna ou converta seu tipo rapidamente ao obter sua soma.

Vamos converter seu tipo rapidamente:
SELECT SUM(CAST(Price AS decimal(8,2))) 
FROM Products; 

Resultado:
48,25

Isso funcionou, felizmente.

Nesse caso, todos os dados no Price coluna pode ser convertida em um tipo numérico.

Se você receber um erro Msg 8114 que lê algo como Erro ao converter o tipo de dados varchar para numérico , isso significa que a coluna contém dados que não podem ser convertidos em numéricos.

O erro se parece com isso:
Mensagem 8114, Nível 16, Estado 5, Linha 1Erro ao converter o tipo de dados varchar para numérico.

Nesse caso, você precisará encontrar os dados não numéricos e decidir o que fazer com eles.

Veja como podemos encontrar os valores não numéricos:
SELECT Price
FROM Products
WHERE ISNUMERIC(Price) <> 1; 

Resultado:
+-------------+| Preço ||-------------|| Dez dólares || Quinze |+-------------+

Encontramos os culpados!

A menos que haja uma boa razão para não fazê-lo, devemos alterar esses valores para seus equivalentes numéricos.

Depois disso, devemos considerar a alteração do tipo de dados da coluna, para que esse tipo de dados não possa ser inserido no futuro. Fazer isso ajudará a reforçar a integridade dos dados.

Uma coisa a ter em mente ao usar o ISNUMERIC() função é que às vezes pode retornar falsos positivos. O que quero dizer é que existem alguns caracteres não numéricos que são interpretados como numéricos. Consulte Caracteres não numéricos que retornam positivos ao usar ISNUMERIC() para mais sobre isso.