Je veux déterminer si une valeur est un entier (comme TryParse
dans .NET). Malheureusement ISNUMERIC
ne me convient pas car je veux analyser uniquement des nombres entiers et non tous les types de nombres. Existe-t-il une chose comme ISINT
ou quelque chose?
Voici un code pour clarifier les choses. Si MY_FIELD
n'est pas int, ce code échouerait:
SELECT @MY_VAR = CAST(MY_FIELD AS INT)
FROM MY_TABLE
WHERE MY_OTHER_FIELD = 'MY_FILTER'
Je vous remercie
Voici un article blog décrivant la création d’un fichier UDF IsInteger
.
En gros, il est recommandé d’ajouter '.e0'
à la valeur et d’utiliser IsNumeric
. De cette manière, tout ce qui avait déjà un point décimal a maintenant deux points décimaux, ce qui rend IsNumeric
faux, et tout ce qui est déjà exprimé en notation scientifique est invalidé par le e0
.
Dans son article Puis-je convertir cette chaîne en un entier? , Itzik Ben-Gan fournit une solution en T-SQL pur et une autre qui utilise le CLR.
Quelle solution devriez-vous choisir?
La solution T-SQL ou CLR est-elle meilleure? L’avantage d’utiliser le T-SQL La solution réside dans le fait que vous n’avez pas besoin de sortir du domaine de T-SQL la programmation. Cependant, la solution CLR présente deux avantages importants: C'est plus simple et plus rapide. Quand j'ai testé les deux solutions sur une table avec 1 000 000 de lignes, la solution CLR a pris deux secondes, plutôt moins de sept secondes (pour la solution T-SQL), à exécuter sur mon ordinateur portable. Alors la prochaine fois que vous devez vérifier si une chaîne donnée peut être converti en un entier, vous pouvez inclure la solution T-SQL ou CLR que j'ai fourni dans cet article.
Si vous souhaitez uniquement conserver T-SQL, utilisez la solution pure T-SQL. Si les performances sont plus importantes que la commodité, utilisez la solution CLR.
La solution T-SQL pure est délicate. Il combine la fonction ISNUMERIC intégrée avec la mise en correspondance des modèles et le transtypage pour vérifier si la chaîne représente un int.
SELECT keycol, string, ISNUMERIC(string) AS is_numeric,
CASE
WHEN ISNUMERIC(string) = 0 THEN 0
WHEN string LIKE '%[^-+ 0-9]%' THEN 0
WHEN CAST(string AS NUMERIC(38, 0))
NOT BETWEEN -2147483648. AND 2147483647. THEN 0
ELSE 1
END AS is_int
FROM dbo.T1;
La partie T-SQL de la solution CLR est plus simple. Vous appelez la fonction fn_IsInt comme vous le feriez avec ISNUMERIC.
SELECT keycol, string, ISNUMERIC(string) AS is_numeric,
dbo.fn_IsInt(string) AS is_int
FROM dbo.T1;
La partie C # est simplement un wrapper pour la fonction d'analyse Int32.TryParse du .NET. Cela fonctionne car int SQL Server et .NET Int32 sont des entiers signés 32 bits.
using System;
using System.Data.SqlTypes;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBoolean fn_IsInt(SqlString s)
{
if (s.IsNull)
return SqlBoolean.False;
else
{
Int32 i = 0;
return Int32.TryParse(s.Value, out i);
}
}
};
Veuillez lire l'article d'Itzik pour une explication complète de ces exemples de code.
Avec sqlserver 2005 et versions ultérieures, vous pouvez utiliser des classes de caractères de type regex avec l'opérateur LIKE. Voir ici .
Pour vérifier si une chaîne est un entier non négatif (il s'agit d'une séquence de chiffres décimaux), vous pouvez vérifier qu'elle ne contient pas d'autres caractères.
SELECT numstr
FROM table
WHERE numstr NOT LIKE '%[^0-9]%'
Note1: Cela retournera aussi des chaînes vides.
Note2: Utiliser LIKE '%[0-9]%'
retournera toute chaîne contenant au moins un chiffre.
Voir violon
WHERE IsNumeric(MY_FIELD) = 1 AND CAST(MY_FIELD as VARCHAR(5)) NOT LIKE '%.%'
C'est probablement la solution la plus simple. Sauf si votre MY_FIELD
contient .00 ou quelque chose de ce genre. Dans ce cas, lancez-le en float pour supprimer les derniers .00s
Ce qui suit est correct pour une clause WHERE
; faire une fonction envelopper dans CASE WHEN
.
ISNUMERIC(table.field) > 0 AND PATINDEX('%[^0123456789]%', table.field) = 0
Voir si la requête ci-dessous aidera
SELECT *
FROM MY_TABLE
WHERE CHARINDEX('.',MY_FIELD) = 0 AND CHARINDEX(',',MY_FIELD) = 0
AND ISNUMERIC(MY_FIELD) = 1 AND CONVERT(FLOAT,MY_FIELD) / 2147483647 <= 1
Ce travail avec la fonction IsNumeric fonctionnera:
sélectionnez * de A où ISNUMERIC (x) = 1 et X pas comme '%.%'
ou utiliser
sélectionnez * de A où x ne ressemble pas à '% [^ 0-9]%'
Je pense qu'il y a quelque chose qui cloche dans la conception de votre base de données. Je pense que c'est une très mauvaise idée de mélanger varchar et des nombres dans une colonne? Quelle est la raison de ceci?
Bien sûr, vous pouvez vérifier s’il existe des caractères autres que [0-9], mais imaginez que vous avez 1 m de lignes dans la table et que vous vérifiez chaque ligne. Je pense que ça ne marchera pas bien.
Quoi qu'il en soit, si vous voulez vraiment le faire, je vous suggère de le faire du côté client.
J'ai le sentiment que le faire de cette façon est l'œuvre de satan, mais au lieu de cela:
Que diriez-vous d'un TRY - CATCH?
DECLARE @Converted as INT
DECLARE @IsNumeric BIT
BEGIN TRY
SET @Converted = cast(@ValueToCheck as int)
SET @IsNumeric=1
END TRY
BEGIN CATCH
SET @IsNumeric=0
END CATCH
select IIF(@IsNumeric=1,'Integer','Not integer') as IsInteger
Cela fonctionne, mais uniquement dans SQL Server 2008 et versions ultérieures.
declare @ i numérique (28,5) = 12,0001 si (@ i/cast (@i comme int)> 1) début sélectionnez 'this is not int' end else begin sélectionnez 'this is int' end
Nécromancie.
À partir de SQL-Server 2012+, vous pouvez utiliser TRY_CAST, qui renvoie NULL si la conversion a échoué.
Exemple:
DECLARE @foo varchar(200)
SET @foo = '0123'
-- SET @foo = '-0123'
-- SET @foo = '+0123'
-- SET @foo = '+-0123'
-- SET @foo = '+-0123'
-- SET @foo = '.123'
-- SET @foo = '1.23'
-- SET @foo = '.'
-- SET @foo = '..'
-- SET @foo = '0123e10'
SELECT CASE WHEN TRY_CAST(@foo AS integer) IS NULL AND @foo IS NOT NULL THEN 0 ELSE 1 END AS isInteger
C'est le seul moyen vraiment fiable.
Si vous avez besoin de support pour SQL-Server 2008, revenez à la réponse de Sam DeHaan:
SELECT CASE WHEN ISNUMERIC(@foo + '.e0') = 1 THEN 1 ELSE 0 END AS isInteger
Je ne suis pas un pro en SQL mais que se passe-t-il en vérifiant s'il est divisible par 1.?.
SELECT *
FROM table
WHERE fieldname % 1 = 0
Parfois, vous ne devez pas concevoir la base de données, vous devez simplement travailler avec ce que vous avez reçu. Dans mon cas, il s’agit d’une base de données située sur un ordinateur auquel je n’ai qu’un accès en lecture et qui existe depuis 2008.
Je dois sélectionner une colonne dans une base de données mal conçue qui est une varchar
avec des nombres de 1 à 100, mais parfois une chaîne aléatoire. J'ai utilisé ce qui suit pour le contourner (bien que j'aurais aimé pouvoir re-concevoir toute la base de données).
SELECT A from TABLE where isnumeric(A)=1
Utilisez PATINDEX
DECLARE @input VARCHAR(10)='102030.40'
SELECT PATINDEX('%[^0-9]%',RTRIM(LTRIM(@input))) AS IsNumber
référence http://www.intellectsql.com/post-how-tocheck-if-the-input-is-numeric/