2009-06-25 10 views
30

Czy istnieje funkcja "konwertuj" na serwerze MS SQL, która pozwala bezpiecznie rzutować typy (bez wyjątku rzucania). Potrzebuję czegoś takiego jak "tryParse" w języku C# lang, ale jako instrukcja SQL.Serwer MS SQL odlewanie bez wyjątku

Bardziej szczegółowe, potrzebuję następujące oświadczenie zwraca zero lub jakiekolwiek inne, ale rzuca wyjątku.

wybierz konwersji (float 'fjsdhf')

z góry dzięki.

Odpowiedz

8

Można sprawdzić, że wartość numeryczna z funkcją IsNumeric TSQL()

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

I, w przypadku gdy nie są już świadomi, TSQL teraz ma konstrukcję TRY CATCH.

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

+0

TRY CATCH nie pasuje do mojego rozwiązania, ponieważ jestem ograniczony i nie mogę dodawać dodatkowych instrukcji. Rozważę dodanie dodatkowej funkcji, która bezpiecznie wykona rzucanie.Coś w stylu "myconvert (typ, dane, wartość domyślna)", zastanawiam się, czy istnieje inny sposób, który uwolniłby mnie od dodania funkcji niestandardowej do bazy danych. – AndrewG

+1

+1 dla TRY..CATCH - to naprawdę droga! –

+1

"SELECT CASE" w poniższej odpowiedzi jest lepsze i bardziej elastyczne niż SPRÓBUJ ... POŁOWU. – TamusJRoyce

3

Jeśli wersja SQL używasz obsługuje CLR można napisać metod stylu TryParse. \ Nie spełnia kryteria dodawania funkcji niestandardowych db chociaż. Ale prawdopodobnie będzie szybszy niż UDF SQL.

coś

[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

ta będzie domyślnie nie-numeryczne 0 i nie będzie wymagać innego oświadczenie:

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

replace() Wywołanie funkcji służy do zmiany okresów przecinków. Przecinki są używane w niektórych kulturach jako separator dziesiętny (np. "1,25" zamiast "1,25"), ale jeśli twój serwer nie jest skonfigurowany z jedną z nich jako domyślną kulturą, ISNUMERIC() zwróci 1, ale CONVERT () rzuci błąd. Ta ma wartość, co oznacza, że ​​ciągi nie powinny używać przecinków jako separatorów tysięcy, ale w większości przypadków przecinek z kropką dziesiętną jest bardziej prawdopodobnym miejscem dziesiętnym.

Wywołanie LTRIM (RTRIM()) jest spowodowane tym, że funkcja ISNUMERIC() zwróci 1 dla ciągu znaków ze spacjami wiodącymi lub końcowymi, ale funkcja CONVERT() nie może ich obsłużyć. Musisz więc przyciąć struny.

Jedyny pozostały potencjalny problem to to, że ISNUMERIC() zwróci 1, jeśli liczba może być reprezentowana jako int, currency, decimal lub float, ale konwertujesz tylko do float. Realistycznie, float może przechowywać prawie wszystko, co na niego rzucasz, ale jeśli próbujesz przekonwertować na int, ISNUMERIC() zwróci 1 dla wartości takiej jak "2.5", ale CONVERT (int, "2.5") nadal rzucać błąd.

+10

W SQL Server 2008 R2 'IsNumeric' zwraca 0 lub 1, a nie boolean. Potrzebujesz 'WHEN ISNUMERIC (myvarcharcolumn) = 1' – row1

+0

Dobry punkt @ row1, poprawiony. – richardtallent

+1

Jest to dobra metoda, ale nadal daje błąd, jeśli kolumna zawiera tylko '-'. – Styxxy

12

w SQL Server 2012 istnieją nowe funkcje do radzenia sobie z tym

try_cast try_convert try_parse

0

FWIW, zważywszy na to pytanie jest prawie 6 lat: W SQL Server 2012 można użyć TRY_CONVERT który zwróci NULL w przypadku błędu; który jest prawdopodobnie dokładnie tym, czego chcesz.