J'ai le code suivant pour convertir nvarchar en entier:
cast(@value as int)
Cependant, je n’ai aucun contrôle sur le paramètre @value, le code peut donc échouer. Est-il possible de vérifier si un casting est possible avant de le faire?
Eh bien, dans SQL Server 2012, vous pouvez utiliser le nouveau TRY_CAST () , mais avec SQL Server 2008, vous devriez pouvoir utiliser ISNUMERIC () , puis inclure la gestion des valeurs qui ne le transmettent pas. tester.
J'ai récemment répondu à une question à ce sujet et utiliser ISNUMERIC
pour CAST
en INT
ne fonctionnera pas tout seul. La raison étant ISNUMERIC
renvoie true pour les nombres non entiers (1.5) par exemple.
Voici une réponse récente sur le sujet:
https://stackoverflow.com/a/14692165/1073631
Envisagez d'ajouter une vérification supplémentaire à l'aide de CHARINDEX avec ISNUMERIC, ou ce que je préfère, utilisez une expression régulière pour valider les données.
Et voici un Fiddle démontrant le problème lié à l'utilisation d'ISNUMERIC seul. Et le Fiddle qui utilise une expression régulière à la place qui fonctionne.
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
Bonne chance.
J'utilise généralement ce qui suit, il semble couvrir toutes les situations.
SELECT CASE WHEN 1 = ISNUMERIC(@value + '.0') THEN CAST(@value as int) ELSE 0 END
Il profite du fait que "ISNUMERIC" ne permettra pas deux périodes. Le "TRY_CAST" dans SQL Server 2012+ est cependant une bien meilleure solution.
Peut-être que nous pouvons faire quelque chose comme ça:
declare @value as nvarchar(10) = 'A';
begin try
select cast(@value as int);
end try
begin catch
-- do something
end catch
Le test approprié est:
select (case when isnumeric(val) = 1 and val not like '%e%' and val not like '%.%'
then cast(val as int)
end)
La fonction isnumeric()
renvoie 1 pour tout ce qui ressemble à un float, vous devez donc faire attention.
Vous pouvez également utiliser ce que je considère être une particularité de SQL Server. Vous pouvez convertir la valeur flottante 1.23 en un entier, mais vous ne pouvez pas convertir la valeur de chaîne. Donc, ce qui suit fonctionne aussi:
select (case when isnumeric(val) = 1
then cast(cast(val as float) as int)
end)
Utilisez une procédure avec un bloc TRY CATCH pour supprimer les erreurs
c'est à dire.
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
Maintenant, vous pouvez appeler cela avec la chaîne passée et le type souhaité et le proc retourne 1 pour succès et 0 pour échec
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'