it-swarm.com.de

sQL Server - Prüfen Sie, ob der Cast möglich ist

Ich habe den folgenden Code, um nvarchar in eine Ganzzahl umzuwandeln:

     cast(@value as int)

Ich habe jedoch keine Kontrolle über den Parameter @value, daher könnte der Code fehlschlagen. Gibt es überhaupt zu prüfen, ob eine Besetzung möglich ist, bevor eine Besetzung durchgeführt wird?

21
Bruce

Nun, in SQL Server 2012 könnten Sie das neue TRY_CAST () verwenden, aber mit SQL Server 2008 sollten Sie ISNUMERIC () verwenden können und dann die Behandlung für Werte einschließen, die das nicht übergeben Prüfung.

24
Matt

Ich habe kürzlich eine Frage dazu beantwortet und die Verwendung von ISNUMERIC in CAST in einer INT funktioniert nicht von alleine. Grund dafür ist, dass ISNUMERIC beispielsweise für nicht ganzzahlige Zahlen (1.5) den Wert true zurückgibt. 

Hier war kürzlich eine Antwort auf das Thema: 

https://stackoverflow.com/a/14692165/1073631

Fügen Sie eine zusätzliche Prüfung hinzu, indem Sie CHARINDEX mit ISNUMERIC verwenden, oder verwenden Sie einen regulären Ausdruck, um die Daten zu überprüfen.

Und hier ist ein Fiddle , das das Problem bei der Verwendung von ISNUMERIC an sich zeigt. Und das Fiddle stattdessen ein regulärer Ausdruck, der funktioniert.

DECLARE @Test nvarchar(10)
SET @Test = '1.5'
--Works
SELECT CASE WHEN @Test NOT LIKE '%[^0-9]%' THEN CAST(@Test as int) ELSE 0 END 
-- Produces Error
SELECT CASE WHEN ISNUMERIC(@Test) = 1 THEN CAST(@Test as int) ELSE 0 END 

Viel Glück.

11
sgeddes

Ich verwende im Allgemeinen Folgendes, es scheint alle Situationen abzudecken.

SELECT CASE WHEN 1 = ISNUMERIC(@value + '.0') THEN CAST(@value as int) ELSE 0 END

Es nutzt die Tatsache, dass "ISNUMERIC" keine zwei Perioden erlaubt. Die "TRY_CAST" in SQL Server 2012+ ist jedoch eine viel bessere Lösung.

7

Vielleicht können wir so etwas machen:

declare @value as nvarchar(10) = 'A';

begin try
    select cast(@value as int);
end try
begin catch
-- do something
end catch
1
Anoop Verma

Der richtige Test ist:

select (case when isnumeric(val) = 1 and val not like '%e%' and val not like '%.%'
             then cast(val as int)
        end)

Die Funktion isnumeric() gibt 1 für alles zurück, was wie ein Float aussieht. Sie müssen also vorsichtig sein.

Sie können auch das verwenden, was ich für eine Besonderheit von SQL Server halte. Sie können den Floating-Wert 1,23 in ein int umwandeln, aber Sie können den String-Wert nicht umwandeln. Also das Folgende funktioniert auch:

select (case when isnumeric(val) = 1
             then cast(cast(val as float) as int)
        end)
1
Gordon Linoff

Verwenden Sie eine Prozedur mit einem TRY CATCH-Block, um Fehler zu unterdrücken

d.h.

CREATE PROCEDURE p_try_cast
 @type nvarchar(MAX),
 @value nvarchar(MAX)
AS
BEGIN

    BEGIN TRY
        DECLARE @sql        varchar(MAX)
        DECLARE @out_table  TABLE(value varchar(MAX))

        SET @sql = 'SELECT  CONVERT(varchar(max), CAST(''' + @value + ''' AS ' + @type + '))'

        INSERT  @out_table
        EXECUTE (@sql)

        IF EXISTS ( SELECT 1 FROM @out_table WHERE value = @value)
            RETURN 1

        RETURN 0
    END TRY
    BEGIN CATCH
        RETURN 0
    END CATCH

END

GO

Jetzt können Sie das mit der übergebenen Zeichenfolge und dem gewünschten Typ aufrufen, und der Prozess gibt 1 für Erfolg und 0 für Fehler zurück

DECLARE @ret int

-- This returns 0 - Fail
EXEC @ret = p_try_cast 'integer', '1.5'

-- This returns 1 - Success
EXEC @ret = p_try_cast 'integer', '1.5'

-- This returns 0 - Fail
EXEC @ret = p_try_cast 'char(4)', 'HELLO'

-- This returns 1 - Success
EXEC @ret = p_try_cast 'char(4)', 'HELL'
0
cmdr_putin