Voici la partie de code que j'utilise dans une procédure stockée SQL Server.
[Time.Minimum] >= 43885.664166666664241
Cela produit cette sortie:
[Time.Minimum] >= 43885.7
qui n'est pas celle attendue et qui a un impact sur le résultat de la procédure. Je ne veux pas que cette valeur numérique soit arrondie. Je veux la valeur flottante complète que j'ai passée. Quelque chose comme ci-dessous.
DECLARE @MinimumTime FLOAT,
@filter VARCHAR(MAX)
SET @MinimumTime = 43885.664166666664241
SELECT @filter = COALESCE('[Time.Minimum] >= ' + CAST(@MinimumTime AS varchar(MAX)), '')
PRINT @filter
S'il vous plaît laissez-moi savoir si vous avez besoin d'informations supplémentaires.
3 Réponses :
Utilisez des paramètres! C'est le seul moyen d'obtenir une valeur flottante "exacte":
declare @sql nvarchar (max);
set @sql = N'
select *
from t
where '[Time.Minimum] >= @MinimumTime
';
exec sp_executesql @sql,
N'@MinimumTime float',
@MinimumTime=@MinimumTime;
En d'autres termes, ne convertissez pas en un chaîne.
Veuillez essayer avec la requête ci-dessous de float à numérique SQL-FIDDLE : XXX
Remarque :
The basic difference between Decimal/Numeric and Float : Float is Approximate-number data type, which means that not all values in the data type range can be represented exactly. Decimal/Numeric is Fixed-Precision data type, which means that all the values in the data type reane can be represented exactly with precision and scale.
Merci à tous pour les réponses, la plupart d'entre eux fonctionnent pour moi, mais celui-ci nécessitera le moins de changement dans le processus existant. J'espère que cela n'a aucun impact négatif sur les performances.
Vous pouvez également utiliser
CONVERTIR
SELECT @filter = COALESCE('[Time.Minimum] >= ' + CONVERT(NVARCHAR(30), @MinimumTime,2), '')
Mais cela vous donnera la sortie en notation scientifique.
Le fait que vous ayez une variable appelée
Filteroù vous essayez de créer la valeur'[Time.Minimum]> = 43885.664166666664241'point très b > fortement à vous injecter des valeurs dans une déclaration dynamique. Cela ressemble à un problème XY . Pourquoi avez-vous besoin d'une instruction dynamique et pourquoi la paramétrez-vous ?Vouloir «la valeur complète» pour une valeur à virgule flottante est très risqué car vous avez déjà affaire à une valeur arrondie lors de l'analyse de la constante.
SELECT FORMAT (@MinimumTime, 'G38')vous donnera autant de chiffres que SQL Server peut vous en donner, mais même cela affichera uniquement43885.664166666669, qui ne peut pas être distingué de43885.664166666664241(après arrondi). Vous obtiendrez une autre valeur (différente) si vous utilisezPARSE, car cela utilise le code .NET -SELECT FORMAT (PARSE ('43885.664166666664241' AS FLOAT), 'G38') code > donne43885.664166666662.Casting Soit de la valeur à
Binary (8) Code> vous montrera la différence entre ceux-ci est littéralement le plus petit possible (0x40E56db540da740d code> vs. code> 0x40E56db540da740e code>). Je ne vais pas obtenir les résultats que vous souhaitez utiliser unfloat code>. Utilisez une chaîne, undécimal code>, un paramètre si vous avez une valeur exacte d'ailleurs ou changez de vos attentes. N'oubliez pas que toute représentation de caractères i> d'une valeur de point flottante introduit un problème de représentation avant même de vous mettre à l'analyser.Vous ne comparez pas les flotteurs de cette façon!