2009-06-25 13 views
30

¿Hay alguna función de "conversión" en el servidor MS SQL que permita lanzar tipos de forma segura (sin lanzar una excepción). Necesito algo como "tryParse" en C# lang pero como declaración de SQL.Fundición del servidor MS SQL sin excepción

Más detallado, necesito la siguiente declaración, devuelve cero o cualquier otra cosa que arrojar una excepción.

select convert (flotador, 'fjsdhf')

gracias de antemano.

Respuesta

8

usted puede probar que es un valor numérico con la función ISNUMERIC TSQL()

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

Y, en caso de que aún no está consciente de ello, TSQL tiene ahora una construcción TRY CATCH.

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

+0

TRY CATCH no encaja en mi solución ya que estoy limitado y no puedo agregar declaraciones adicionales. Considero agregar funciones adicionales que harán el casting de forma segura.Algo así como, "myconvert (tipo, datos, valor predeterminado)", me pregunto si hay otra manera que me libre de agregar funciones personalizadas en la base de datos. – AndrewG

+1

+1 por TRY..CATCH - ¡ese es realmente el camino a seguir! –

+1

"SELECCIONAR CASO" en la respuesta a continuación es mejor y más flexible que TRY ... CATCH. – TamusJRoyce

3

Si la versión de SQL que está utilizando soporta el CLR puede escribir métodos de estilo TryParse. \ No cumple con los criterios de la adición de funciones personalizadas a la db sin embargo. Pero probablemente sea más rápido que un UDF de SQL.

algo así como

[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

Esto será por defecto no numéricos a 0 y no requerirá otra declaración:

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

La llamada a la función replace() se utiliza para cambiar comas para periodos. Las comas se utilizan en algunas culturas como un separador decimal (por ejemplo, "1,25" en lugar de "1,25"), pero a menos que su servidor esté configurado con una de esas como cultura predeterminada, ISNUMERIC() devolverá 1 pero CONVERTIR () lanzará un error. Esto hace significa que sus cadenas no deben usar comas como separadores de miles, pero en la mayoría de los casos, una coma para un marcador de posición decimal es más probable que sea un marcador de posición decimal.

La llamada LTRIM (RTRIM()) se debe a que ISNUMERIC() devolverá 1 para una cadena con espacios iniciales o finales, pero CONVERT() no puede tratar con ellos. Entonces, debes recortar tus cadenas.

El único problema potencial restante es que ISNUMERIC() devolverá 1 si el número se puede representar como int, currency, decimal o float, pero solo se está convirtiendo en un flotante. De manera realista, un flotador puede almacenar casi cualquier cosa que le arroje, pero si intentara convertirlo a int, ISNUMERIC() devolvería 1 para un valor como "2.5", pero CONVERT (int, '2.5') aún lanzar un error.

+10

En SQL Server 2008 R2 'IsNumeric' devuelve 0 o 1 y no es booleano. Por lo tanto, necesita 'WHEN ISNUMERIC (myvarcharcolumn) = 1' – row1

+0

Good point @ row1, fixed. – richardtallent

+1

Es un buen método, pero todavía da un error si la columna solo contiene '-'. – Styxxy

12

En SQL SERVER 2012 de nuevas funciones para hacer frente a este

try_cast try_convert try_parse

0

Fwiw, teniendo en cuenta esta cuestión es casi 6 años de edad: En SQL Server 2012 puede utilizar TRY_CONVERT que devolverá NULL en error; que es probablemente lo que quieres.

Cuestiones relacionadas