2009-06-25 7 views
30

Gibt es irgendeine "konvertieren" -Funktion in MS SQL-Server, die Typen sicher zu werfen (ohne Ausnahme zu werfen) ermöglicht. Ich brauche etwas wie "tryParse" in C# lang aber als SQL-Anweisung.MS SQL Server Casting ohne Ausnahme

Detaillierter, brauche ich die folgende Anweisung gibt Null oder sonst irgendwas außer Ausnahme werfen.

select convert (float, 'fjsdhf')

Dank im Voraus.

Antwort

8

Sie können testen, ob ein Wert mit dem T-SQL-Funktion ISNUMERIC numerisch ist()

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

Und, falls Sie nicht bereits dessen bewusst sind, TSQL hat jetzt ein TRY CATCH-Konstrukt.

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

+0

TRY CATCH passt nicht in meine Lösung, da ich eingeschränkt bin und keine zusätzlichen Anweisungen hinzufügen kann. Ich denke, zusätzliche Funktion hinzufügen, die Casting sicher tun wird.Etwas wie "myconvert (type, data, default value)", frage ich mich, ob es eine andere Möglichkeit gibt, die mich von der benutzerdefinierten Funktion in die Datenbank hinzufügen würde. – AndrewG

+1

+1 für TRY..CATCH - das ist wirklich der Weg! –

+1

"SELECT CASE" in der folgenden Antwort ist besser und flexibler als TRY ... CATCH. – TamusJRoyce

3

Wenn die Version von SQL sind Sie unterstützt die CLR verwenden, können Sie TryParse Stil Methoden schreiben. \ Es entspricht nicht Ihren Kriterien obwohl benutzerdefinierte Funktionen zum db hinzufügen. Aber es wird wahrscheinlich schneller als eine SQL UDF sein.

so etwas wie

[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

Dies wird nicht-numerische Werte auf 0 Standard und wird keine weitere Erklärung erforderlich:

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

Die REPLACE() Funktionsaufruf verwendet wird Kommas auf Zeiträume zu ändern. Kommas werden in einigen Kulturen als Dezimaltrennzeichen verwendet (z. B. "1,25" anstelle von "1,25"), aber wenn Ihr Server nicht mit einer dieser als Standardkultur eingerichtet ist, gibt ISNUMERIC() 1 zurück, aber CONVERT () wird einen Fehler auslösen. Diese bedeutet bedeutet, dass Ihre Zeichenfolgen keine Kommas als Tausendertrennzeichen verwenden sollten, aber in den meisten Fällen ist ein Komma für einen Dezimal-Platzhalter wahrscheinlicher ein Dezimal-Platzhalter.

Der Aufruf von LTRIM (RTRIM()) ist, da ISNUMERIC() 1 für eine Zeichenfolge mit führenden oder abschließenden Leerzeichen zurückgeben wird, aber CONVERT() kann nicht mit ihnen umgehen. Also, Sie müssen Ihre Saiten trimmen.

Das einzige verbleibende potenzielle Problem ist, dass ISNUMERIC() 1 zurückgibt, wenn die Zahl als int, Währung, Dezimalzahl oder Gleitkommazahl dargestellt werden kann, aber Sie nur in eine Gleitkommazahl konvertieren. Realistisch gesehen, kann ein Float alles speichern, was Sie darauf werfen, aber wenn Sie stattdessen versuchen, zu einem int zu konvertieren, würde ISNUMERIC() 1 für einen Wert wie "2.5" zurückgeben, aber CONVERT (int, '2.5') immer noch einen Fehler werfen.

+10

In SQL Server 2008 R2 gibt 'IsNumeric' 0 oder 1 zurück und keinen booleschen Wert. Also brauchen Sie 'WENN ISNUMERIC (myvarcharcolumn) = 1' – row1

+0

Guter Punkt @ row1, behoben. – richardtallent

+1

Es ist eine gute Methode, gibt aber immer noch einen Fehler, wenn die Spalte nur '-' enthält. – Styxxy

12

In SQL Server 2012 gibt es neue Funktionen mit diesem

try_cast try_convert try_parse

0

FWIW zu beschäftigen, diese Frage unter Berücksichtigung ist fast 6 Jahre: In SQL Server 2012 können Sie TRY_CONVERT verwenden, die NULL zurück im Fehlerfall; was wahrscheinlich genau das ist, was du willst.