2009-06-25 6 views
30

Esiste una funzione di "conversione" in MS SQL server che consente di eseguire il cast dei tipi in modo sicuro (senza generare eccezioni). Ho bisogno di qualcosa come "tryParse" in C# lang ma come istruzione SQL.Trasmissione di server MS SQL senza eccezioni

Più dettagliato, ho bisogno della seguente dichiarazione restituisce zero o qualsiasi altra eccezione di eccezione di lancio.

select convert (float, 'fjsdhf')

grazie in anticipo.

risposta

8

È possibile verificare che un valore è numerico con la funzione TSQL ISNUMERIC()

http://msdn.microsoft.com/en-us/library/ms186272.aspx

E, nel caso in cui non siete già a conoscenza di essa, TSQL ora ha un costrutto TRY CATCH.

http://msdn.microsoft.com/en-us/library/ms179296.aspx

+0

TRY CATCH non è adatto alla mia soluzione poiché sono limitato e non posso aggiungere ulteriori istruzioni. Considero di aggiungere una funzione extra che farà il casting in sicurezza.Qualcosa come "myconvert (type, data, default value)", mi chiedo se c'è un altro modo per liberarmi dall'aggiungere funzioni personalizzate nel database. – AndrewG

+1

+1 per TRY..CATCH - questa è davvero la strada da percorrere! –

+1

"SELECT CASE" nella risposta seguente è migliore e più flessibile di TRY ... CATCH. – TamusJRoyce

3

Se la versione di SQL si sta utilizzando supporti il ​​CLR è possibile scrivere i metodi di stile TryParse. \ Non corrispondono ai tuoi criteri di aggiungere funzioni personalizzate al db però. Ma probabilmente sarà più veloce di un UDF di SQL.

qualcosa come

[SqlFunction] 
public static SqlDouble TryParseDouble(SqlString str) 
{ 
    Double d; 
    bool success = Double.TryParse(str, out d); 
    if (!success) 
    return SqlDouble.Null; 
    return new SqlDouble(d); 
} 
34

Questo stabilizzerà non numerici a 0 e non richiederà un'altra dichiarazione:

SELECT CASE 
    WHEN ISNUMERIC(myvarcharcolumn)=1 THEN 
     CONVERT(float, REPLACE(LTRIM(RTRIM(myvarcharcolumn)), ',', '.')) 
    ELSE 0 END AS myfloatcolumn 

La chiamata di funzione replace() viene utilizzata per modificare le virgole per periodi. Le virgole vengono utilizzate in alcune culture come separatore decimale (ad esempio "1,25" anziché "1,25"), ma a meno che il server non sia impostato con una di quelle come cultura predefinita, ISNUMERIC() restituirà 1 ma CONVERT () genererà un errore. Questo fa significa che le tue stringhe non dovrebbero usare virgole come separatori di migliaia, ma nella maggior parte dei casi, una virgola per un segnaposto decimale è più probabile che sia un segnaposto decimale.

La chiamata LTRIM (RTRIM()) è perché ISNUMERIC() restituirà 1 per una stringa con spazi iniziali o finali, ma CONVERT() non può gestirli. Quindi, devi tagliare le corde.

L'unico problema potenziale rimanente è che ISNUMERIC() restituirà 1 se il numero può essere rappresentato come int, currency, decimal o float, ma si sta solo convertendo in float. Realisticamente, un float può memorizzare qualsiasi cosa tu passi, ma se stavi cercando di convertire in un int invece, ISNUMERIC() restituirebbe 1 per un valore come "2.5", ma CONVERT (int, '2.5') ancora lanciare un errore.

+10

In SQL Server 2008 R2 'IsNumeric' restituisce 0 o 1 e non un valore booleano. Quindi è necessario 'WHEN ISNUMERIC (myvarcharcolumn) = 1' – row1

+0

Good point @ row1, corretto. – richardtallent

+1

È un buon metodo, ma dà comunque un errore se la colonna contiene solo '-'. – Styxxy

12

In SQL Server 2012 sono disponibili nuove funzionalità per affrontare questo

try_cast try_convert try_parse

0

FWIW, considerando questa domanda è quasi 6 anni: In SQL Server 2012 è possibile utilizzare TRY_CONVERT che restituirà NULL su errore; che è probabilmente esattamente quello che vuoi.