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.
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 per TRY..CATCH - questa è davvero la strada da percorrere! –
"SELECT CASE" nella risposta seguente è migliore e più flessibile di TRY ... CATCH. – TamusJRoyce