2010-03-10 13 views
7

Ho una colonna varchar (100) in una tabella che contiene un insieme di stringhe di numeri interi (come stringhe) e non interi. Per esempio.SQL Server 2005 Converti VARCHAR in INT ma predefinito su tipo non valido

| dimension varchar(100) | 
| '5'     | 
| '17'     | 
| '3'     | 
| 'Pyramids'    | 
| 'Western Bypass'  | 
| '15'     | 

Come posso scrivere un'espressione, ad es. riassumere tutti i valori che sono interi validi? Se dovessi provare:

-- should return 5 + 17 + 3 + 15 = 40 
SELECT 
    SUM(CONVERT(INT, dimension)) 
FROM 
    mytable 

avrei ricevuto un errore di Conversion failed when converting the varchar value 'Pyramids' to data type int..

Esiste un test che posso utilizzare nella mia espressione, proprio come la funzione ISNULL(), che mi consente di specificare un valore predefinito se il campo non è un numero?

risposta

20

Prova questo:

SELECT 
    SUM(CASE ISNUMERIC(dimension) 
      WHEN 1 THEN CONVERT(INT, dimension) 
      ELSE 0 
     END) 
FROM 
    mytable 

il caso dovrebbe verificare se dimension è numerica - in caso affermativo, riportare tale valore. Se non è numerico, restituire un valore predefinito (qui: 0)

È necessario eseguire una query piuttosto frequente, è inoltre possibile aggiungere una colonna calcolata e persistente alla tabella che incapsula questo calcolo e memorizza il valore. In questo modo, quando si somma e così via, tu non sempre ri-calcolare il valore:

ALTER TABLE mytable 
    ADD NumericValue AS CASE ISNUMERIC(dimension) 
     WHEN 1 THEN CONVERT(INT, dimension) ELSE 0 END PERSISTED 

Ora, è possibile SELECT dimension, numericvalue FROM mytable e ottenere entrambi i valori, senza alcun calcolo dover essere eseguito.

+0

Perfetto! Grazie! 'ISNUMERIC ('- 1.44')' e 'ISNUMERIC ('12')' restituisce 1 mentre 'ISNUMERIC ('foobar')' restituisce 0. Proprio ciò di cui avevo bisogno. –

1

avete intenzione di incorrere in problemi di overflow se si dispone di un varchar come 88888888888888888888888

select 
SUM(
    CASE 
     WHEN ISNUMERIC(CheckCol+ '.0e0') = 1 AND 
     convert(decimal(38,0), CheckCol) 
     BETWEEN -2147483648 AND 2147483647 
    THEN 1 
    ELSE 0 
    END 
) 
from Table 
Problemi correlati