sql >> Databáze >  >> RDS >> Sqlserver

Oprava Msg 8117 „Datový typ operandu varchar je neplatný pro operátor součtu“ v SQL Server

Pokud se vám zobrazuje chyba SQL Server Msg 8117 se zprávou Datový typ operandu varchar je neplatný pro operátor součtu , je to proto, že operátorovi nebo funkci předáváte nesprávný datový typ.

V tomto případě chyba znamená, že předáváme řetězec do SUM() funkce. Tje SUM() funkce nefunguje na řetězcích. Funguje pouze na číselných typech.

Ke stejné chybě (Msg 8117) může dojít i v jiných kontextech – není omezena na SUM() funkce.

Příklad chyby

Zde je příklad kódu, který způsobuje chybu:

SELECT SUM(ProductName) 
FROM Products; 

Výsledek:

Zpráva 8117, úroveň 16, stav 1, řádek 1Operand datový typ varchar je neplatný pro operátor součtu.

V tomto případě se snažíme přidat ProductName sloupec.

V tomto případě je vysoce pravděpodobné, že ProductName sloupec je varchar sloupec. Pravděpodobně máme špatný sloupec.

Řešení 1

Abychom tuto chybu opravili, měli bychom nejprve zkontrolovat, zda máme správný sloupec. Pokud nemáme správný sloupec, změňte jej na správný sloupec:

SELECT SUM(Price) 
FROM Products; 

Snad to problém vyřeší. Jinými slovy, doufejme, že Price sloupec je číselný, jak by měl být.

Ale co když ne?

Řešení 2

V některých případech můžete zjistit, že máte správný sloupec, ale tento sloupec používá nevhodný datový typ. Předpokládejme například naše Price sloupec byl ve skutečnosti definován jako varchar sloupec.

V takovém případě bychom dostali stejnou chybu:

SELECT SUM(Price) 
FROM Products; 

Výsledek:

Zpráva 8117, úroveň 16, stav 1, řádek 1Operand datový typ varchar je neplatný pro operátor součtu.

Na první pohled se zdá, že na tomto prohlášení není nic špatného. Vše, co děláme, je získání součtu hodnot v Price sloupec. Toto je dokonalý příklad toho, co SUM() funkce byla navržena k tomu.

Samozřejmě se zde předpokládá, že Price sloupec je číselný. Ale podle chybové zprávy to není numerické – je to varchar .

Zkontrolujeme datový typ sloupce:

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

Výsledek:

+-------------+-------------+----------------+ | DATA_TYPE | MAX_LENGTH | OCTET_DÉLKA ||-------------+--------------+----------------|| varchar | 255 | 255 |+-------------+--------------+----------------+ 

Podle podezření je sloupec typu varchar .

V tomto případě máme dvě možnosti; změnit typ sloupce nebo převést jeho typ za běhu při získávání jeho součtu.

Převedeme jeho typ za běhu:

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

Výsledek:

48,25

To naštěstí fungovalo.

V tomto případě jsou všechny údaje v Price sloupec lze převést na číselný typ.

Pokud se zobrazí chybová zpráva 8114, která zní něco jako Chyba při převodu datového typu varchar na číselný , pak to znamená, že sloupec obsahuje data, která nelze převést na číselná.

Chyba vypadá takto:

Zpráva 8114, úroveň 16, stav 5, řádek 1Chyba při převodu datového typu varchar na číselný.

V tomto případě budete muset najít nečíselná data a rozhodnout se, co s nimi uděláte.

Zde je návod, jak můžeme najít nečíselné hodnoty:

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

Výsledek:

+--------------+| Cena ||--------------|| Deset dolarů || Patnáct |+-------------+

Našli jsme viníky!

Pokud neexistuje dobrý důvod, proč tomu tak není, měli bychom tyto hodnoty změnit na jejich číselné ekvivalenty.

Poté bychom měli zvážit změnu datového typu sloupce, aby tento typ dat nebylo možné vkládat v budoucnu. To pomůže zajistit integritu dat.

Při používání ISNUMERIC() je třeba mít na paměti jednu věc funkcí je, že někdy může vrátit falešně pozitivní výsledky. Chci říct, že existují některé nečíselné znaky, které jsou interpretovány jako číselné. Viz Nečíselné znaky, které se vrátí jako kladné při použití ISNUMERIC() pro více informací.


  1. Cross Join v Oracle

  2. Zálohujte své databáze MySQL

  3. Zřetězit hodnoty řádků T-SQL

  4. Aktualizace verze Docker PGMASTER PostgreSQL