sql >> Databasteknik >  >> RDS >> Sqlserver

Fix Msg 8117 "Operand data type varchar är ogiltig för sumoperator" i SQL Server

Om du får SQL Server-felmeddelande 8117 med meddelandet Operanddatatypen varchar är ogiltig för sumoperatorn , det beror på att du skickar fel datatyp till en operatör eller funktion.

I det här fallet indikerar felet att vi skickar en sträng till SUM() fungera. The SUM() funktionen fungerar inte på strängar. Det fungerar bara på numeriska typer.

Samma fel (Msg 8117) kan också uppstå i andra sammanhang – det är inte begränsat till SUM() funktion.

Exempel på felet

Här är ett exempel på kod som ger felet:

SELECT SUM(ProductName) 
FROM Products;

Resultat:

Msg 8117, Level 16, State 1, Line 1
Operand data type varchar is invalid for sum operator.

I det här fallet försöker vi lägga till ProductName kolumn.

I det här fallet är det mycket troligt att ProductName kolumn är en varchar kolumn. Vi har förmodligen fel kolumn.

Lösning 1

För att åtgärda det här felet bör vi först kontrollera att vi har rätt kolumn. Om vi ​​inte har rätt kolumn, ändra den till rätt kolumn:

SELECT SUM(Price) 
FROM Products;

Förhoppningsvis löser det problemet. Med andra ord, förhoppningsvis Price kolumnen är numerisk, som den borde vara.

Men vad händer om det inte är det?

Lösning 2

I vissa fall kan du upptäcka att du har rätt kolumn, men den kolumnen använder en olämplig datatyp. Anta till exempel vårt Price kolumnen definierades faktiskt som en varchar kolumn.

I så fall skulle vi få samma felmeddelande:

SELECT SUM(Price) 
FROM Products;

Resultat:

Msg 8117, Level 16, State 1, Line 1
Operand data type varchar is invalid for sum operator.

Vid första anblick verkar inget vara fel med detta uttalande. Allt vi gör är att få en total av värdena i Price kolumn. Detta är ett perfekt exempel på vad SUM() funktion designades för att göra.

Naturligtvis är antagandet här att Price kolumnen är numerisk. Men enligt felmeddelandet är det inte numeriskt – det är en varchar .

Låt oss kontrollera kolumnens datatyp:

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';

Resultat:

+-------------+--------------+----------------+
| DATA_TYPE   | MAX_LENGTH   | OCTET_LENGTH   |
|-------------+--------------+----------------|
| varchar     | 255          | 255            |
+-------------+--------------+----------------+

Som misstänkt är kolumnen av typen varchar .

I det här fallet har vi två alternativ; ändra kolumnens typ, eller konvertera dess typ direkt när du får dess summa.

Låt oss konvertera dess typ i farten:

SELECT SUM(CAST(Price AS decimal(8,2))) 
FROM Products;

Resultat:

48.25

Detta fungerade lyckligtvis.

I det här fallet, all data i Price kolumn kan konverteras till en numerisk typ.

Om du får felmeddelande 8114 som lyder något som Fel vid konvertering av datatyp varchar till numerisk , då betyder det att kolumnen innehåller data som inte kan konverteras till numeriska.

Felet ser ut så här:

Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.

I det här fallet måste du hitta den icke-numeriska informationen och bestämma vad du ska göra med den.

Så här kan vi hitta de icke-numeriska värdena:

SELECT Price
FROM Products
WHERE ISNUMERIC(Price) <> 1;

Resultat:

+-------------+
| Price       |
|-------------|
| Ten dollars |
| Fifteen     |
+-------------+

Vi har hittat de skyldiga!

Om det inte finns en bra anledning att inte göra det, bör vi ändra dessa värden till deras numeriska motsvarigheter.

Efter det bör vi överväga att ändra kolumnens datatyp, så att denna typ av data inte kan infogas i framtiden. Att göra detta kommer att hjälpa till att upprätthålla dataintegritet.

En sak att vara uppmärksam på när du använder ISNUMERIC() Funktionen är att den ibland kan returnera falska positiva resultat. Vad jag menar är att det finns några icke-numeriska tecken som tolkas som numeriska. Se icke-siffertecken som returnerar positivt när du använder ISNUMERIC() för mer om detta.


  1. LEN-funktionen inkluderar inte efterföljande mellanslag i SQL Server

  2. Hur man exporterar frågeresultat till en CSV-fil i SQL Developer (Oracle)

  3. MySQL-syntax för Join Update

  4. Hög tillgänglighet på en knapp budget - Utplacera ett MySQL Galera-kluster med minst två noder