2009-06-25 8 views
30

Y at-il une fonction de "conversion" dans le serveur MS SQL qui permet de lancer des types en toute sécurité (sans lancer d'exception). J'ai besoin de quelque chose comme "tryParse" dans C# lang mais comme instruction SQL.Coulée de serveur MS SQL sans exception

Plus détaillée, j'ai besoin de l'instruction suivante renvoie zéro ou toute autre exception de lancement.

select convert (float, 'fjsdhf')

merci à l'avance.

Répondre

8

Vous pouvez tester qu'une valeur est numérique avec la fonction TSQL ISNUMERIC()

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

Et, au cas où vous n'êtes pas déjà au courant, TSQL a maintenant une construction ESSAYER CATCH.

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

+0

TRY CATCH ne rentre pas dans ma solution car je suis limité et je ne peux pas ajouter d'instructions supplémentaires. J'envisage d'ajouter une fonction supplémentaire qui fera du casting en toute sécurité.Quelque chose comme, "myconvert (type, données, valeur par défaut)", je me demande s'il existe un autre moyen qui me libérerait de l'ajout de fonction personnalisée dans la base de données. – AndrewG

+1

+1 pour TRY..CATCH - c'est vraiment le chemin à parcourir! –

+1

"SELECT CASE" dans la réponse ci-dessous est mieux et plus flexible que TRY ... CATCH. – TamusJRoyce

3

Si la version de SQL utilisé prend en charge le CLR, vous pouvez écrire des méthodes de style TryParse. \ Il ne répond pas à vos critères d'ajouter des fonctions personnalisées à la db bien. Mais il va probablement être plus rapide qu'un SQL UDF.

quelque chose comme

[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

Ce sera par défaut non-numerics à 0 et ne nécessitera pas une autre déclaration:

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

L'appel de fonction REPLACE() est utilisée pour changer des virgules pour les périodes. Les virgules sont utilisées dans certaines cultures comme un séparateur décimal (par exemple, «1,25» au lieu de «1,25»), mais à moins que votre serveur ne soit configuré avec l'une de ces valeurs par défaut, ISNUMERIC() renvoie 1 mais CONVERT () va lancer une erreur. Cette signifie que vos chaînes ne doivent pas utiliser de virgules comme des séparateurs de milliers, mais dans la plupart des cas, une virgule pour un espace réservé décimal est plus susceptible d'être un espace réservé décimal. L'appel LTRIM (RTRIM()) est parce que ISNUMERIC() retournera 1 pour une chaîne avec des espaces de début ou de fin, mais CONVERT() ne peut pas traiter avec eux. Donc, vous devez couper vos cordes. Le seul problème potentiel restant est que ISNUMERIC() renvoie 1 si le nombre peut être représenté comme int, currency, decimal ou float, mais que vous convertissez uniquement en float. De manière réaliste, un flottant peut stocker à peu près tout ce que vous lui lancez, mais si vous essayez de convertir en un int à la place, ISNUMERIC() retournera 1 pour une valeur comme "2.5", mais CONVERT (int, '2.5') encore jeter une erreur.

+10

Dans SQL Server 2008 R2 'IsNumeric' renvoie 0 ou 1 et non un booléen. Vous avez donc besoin de 'WHEN ISNUMERIC (myvarcharcolumn) = 1' – row1

+0

Bon point @ row1, corrigé. – richardtallent

+1

C'est une bonne méthode, mais donne quand même une erreur si la colonne contient seulement '-'. – Styxxy

12

Dans SQL Server 2012, il y a de nouvelles fonctions pour faire face à ce

try_cast try_convert try_parse

0

FWIW, compte tenu de cette question est presque 6 ans: En SQL Server 2012 vous pouvez utiliser TRY_CONVERT qui retournera NULL en erreur ce qui est probablement exactement ce que vous voulez.

Questions connexes