Existe-t-il un moyen dans T-SQL de convertir un nvarchar en int et de renvoyer une valeur par défaut ou NULL si la conversion échoue?
116
Utilisez la fonction TRY_CONVERT .
Créez une fonction définie par l'utilisateur. Cela évitera les problèmes mentionnés par Fedor Hajdu en ce qui concerne la devise, les nombres fractionnaires, etc.:
CREATE FUNCTION dbo.TryConvertInt(@Value varchar(18))
RETURNS int
AS
BEGIN
SET @Value = REPLACE(@Value, ',', '')
IF ISNUMERIC(@Value + 'e0') = 0 RETURN NULL
IF ( CHARINDEX('.', @Value) > 0 AND CONVERT(bigint, PARSENAME(@Value, 1)) <> 0 ) RETURN NULL
DECLARE @I bigint =
CASE
WHEN CHARINDEX('.', @Value) > 0 THEN CONVERT(bigint, PARSENAME(@Value, 2))
ELSE CONVERT(bigint, @Value)
END
IF ABS(@I) > 2147483647 RETURN NULL
RETURN @I
END
GO
-- Testing
DECLARE @Test TABLE(Value nvarchar(50)) -- Result
INSERT INTO @Test SELECT '1234' -- 1234
INSERT INTO @Test SELECT '1,234' -- 1234
INSERT INTO @Test SELECT '1234.0' -- 1234
INSERT INTO @Test SELECT '-1234' -- -1234
INSERT INTO @Test SELECT '$1234' -- NULL
INSERT INTO @Test SELECT '1234e10' -- NULL
INSERT INTO @Test SELECT '1234 5678' -- NULL
INSERT INTO @Test SELECT '123-456' -- NULL
INSERT INTO @Test SELECT '1234.5' -- NULL
INSERT INTO @Test SELECT '123456789000000' -- NULL
INSERT INTO @Test SELECT 'N/A' -- NULL
SELECT Value, dbo.TryConvertInt(Value) FROM @Test
Référence: J'ai beaucoup utilisé cette page lors de la création de ma solution.
Oui :). Essaye ça:
ISNUMERIC()
a quelques problèmes signalés par Fedor Hajdu .Il renvoie true pour les chaînes telles que
$
(is currency),,
or.
(les deux sont des séparateurs)+
et-
.la source
ISNUMERIC
pour que cette réponse soit utile sur des données non validées (et vous n'auriez pas besoin de laISNUMERIC
vérification en premier lieu pour des données correctement validées). L'auteur reconnaît l'existence de ces problèmes mais ne les aborde pas.TRY_CONVERT
/TRY_CAST
, qui sont explicitement destinés à résoudre la question du PO. Cette réponse a été écrite avant la publication de SQL 2012.Je préfère créer une fonction comme TryParse ou utiliser le
TRY-CATCH
bloc T-SQL pour obtenir ce que vous voulez.ISNUMERIC ne fonctionne pas toujours comme prévu. Le code donné précédemment échouera si vous faites:
SET @text = '$'
$ sign peut être converti en type de données money, donc
ISNUMERIC()
renvoie true dans ce cas. Il en sera de même pour '-' (moins), ',' (virgule) et '.' personnages.la source
ISNUMERIC()
rendement1
aussi pour,
et.
.Comme cela a été mentionné, vous pouvez rencontrer plusieurs problèmes si vous utilisez
ISNUMERIC
:Si vous voulez une conversion fiable, vous devrez en coder une vous-même.
Mise à jour : Ma nouvelle recommandation serait d'utiliser une conversion de test intermédiaire
FLOAT
pour valider le numéro. Cette approche est basée sur le commentaire d'Adrianm . La logique peut être définie comme une fonction table en ligne:Quelques tests:
Les résultats sont similaires à la réponse de Joseph Sturtevant , avec les principales différences suivantes:
.
ou,
pour imiter le comportement desINT
conversions natives .'1,234'
et'1234.0'
revenirNULL
.'00000000000000001234'
évalue à12
. L'augmentation de la longueur du paramètre entraînerait des erreurs sur les nombres qui débordentBIGINT
, tels que les BBAN (numéros de compte bancaire de base) comme'212110090000000235698741'
.Retiré : L'approche ci-dessous n'est plus recommandée, car elle est laissée juste pour référence.
L'extrait ci-dessous fonctionne sur des entiers non négatifs. Il vérifie que votre chaîne ne contient aucun caractère non numérique, n'est pas vide et ne déborde pas (en dépassant la valeur maximale du
int
type). Cependant, il donne égalementNULL
des entiers valides dont la longueur dépasse 10 caractères en raison de zéros non significatifs.Si vous souhaitez prendre en charge un nombre quelconque de zéros non significatifs, utilisez ce qui suit. Les
CASE
instructions imbriquées , bien que peu maniables, sont nécessaires pour promouvoir l'évaluation de court-circuit et réduire la probabilité d'erreurs (résultant, par exemple, du passage d'une longueur négative àLEFT
).Si vous souhaitez prendre en charge les entiers positifs et négatifs avec un nombre quelconque de zéros non significatifs:
la source
Cordialement.
J'ai écrit une fonction scalaire utile pour simuler la fonction TRY_CAST de SQL SERVER 2012 dans SQL Server 2008.
Vous pouvez le voir dans le lien suivant ci-dessous et nous nous entraidons pour l'améliorer. Fonction TRY_CAST pour SQL Server 2008 https://gist.github.com/jotapardo/800881eba8c5072eb8d99ce6eb74c8bb
Exemple:
Pour l'instant ne prend en charge que les types de données INT, DATE, NUMERIC, BIT et FLOAT
J'espère que tu trouves cela utile.
CODE:
la source
La réponse de Joseph a souligné que ISNUMERIC gère également la notation scientifique comme «1.3e + 3» mais sa réponse ne gère pas ce format de nombre.
La conversion en argent ou en flottant traite d'abord à la fois la monnaie et les questions scientifiques:
La fonction échouera si le nombre est plus grand qu'un bigint.
Si vous souhaitez renvoyer une valeur par défaut différente, laissez cette fonction pour qu'elle soit générique et remplacez la valeur nulle par la suite:
la source
Je sais que ce n'est pas joli mais c'est simple. Essaye ça:
la source
Ma solution à ce problème était de créer la fonction ci-dessous. Mes exigences incluaient que le nombre devait être un entier standard, pas un BIGINT, et je devais autoriser les nombres négatifs et positifs. Je n'ai trouvé aucune circonstance où cela échoue.
la source