web-dev-qa-db-fra.com

Comment convertir float en varchar dans SQL Server

J'ai une colonne float avec des nombres de longueurs différentes et j'essaie de les convertir en varchar.

Certaines valeurs dépassent la taille maximale de bigint, je ne peux donc pas faire quelque chose comme ça

cast(cast(float_field as bigint) as varchar(100))

J'ai essayé d'utiliser décimal, mais les nombres ne sont pas de la même taille, donc cela n'aide pas trop

CONVERT(varchar(100), Cast(float_field as decimal(38, 0)))

Toute aide est appréciée.

METTRE À JOUR:

La valeur de l'échantillon est 2.2000012095022E + 26 .

108
hgulyan

Essayez d’utiliser la fonction STR().

SELECT STR(float_field, 25, 5)

Fonction STR ()


Une autre remarque: cette touche à gauche avec des espaces. Si cela pose un problème, combinez-le avec LTRIM:

SELECT LTRIM(STR(float_field, 25, 5))
201
codingbadger

Le seul bit de requête que j'ai trouvé qui retourne le même numéro original EXACT est 

CONVERT (VARCHAR(50), float_field,128)

Voir http://www.connectsql.com/2011/04/normal-0-microsoftinternetexplorer4.html

Les autres solutions ci-dessus arrondissent ou ajoutent parfois des chiffres à la fin

UPDATE: Selon les commentaires ci-dessous et ce que je peux voir dans https://msdn.Microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Doit être utilisé dans les nouvelles versions de SQL Server (base de données Azure SQL et à partir de SQL Server 2016 RC3)

30
adinas

c'est la solution que j'ai finalement utilisée dans sqlserver 2012 (toutes les autres suggestions ayant l'inconvénient de tronquer une partie fractionnaire ou un autre inconvénient).

declare @float float = 1000000000.1234;
select format(@float, N'#.##############################');

sortie:

1000000000.1234

cela a l’avantage supplémentaire (dans mon cas) de faciliter la séparation et la localisation des milliers:

select format(@float, N'#,##0.##########', 'de-DE');

sortie:

1.000.000.000,1234
12
molecular

Sujet utile merci.

Si vous voulez comme moi supprimer le zéro non significatif, vous pouvez l'utiliser:

DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;
SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(LTRIM(REPLACE(STR(@MyFloat, 38, 16), '0', ' '))), ' ', '0'),'.',' ')),' ',',')
2
Axel

Convertissez d'abord en integer, puis en string:

cast((convert(int,b.tax_id)) as varchar(20))
2
Amit Patil

Cela peut aider sans arrondir

declare @test float(25)

declare @test1 decimal(10,5)

select @test = 34.0387597207
select @test
set @test1 = convert (decimal(10,5), @test)
select cast((@test1) as varchar(12))


Select  LEFT(cast((@test1) as varchar(12)),LEN(cast((@test1) as varchar(12)))-1)
2
Atul

float a seulement un max. précision de 15 chiffres. Les chiffres après la 15e position sont donc aléatoires et la conversion en bigint (19 chiffres maximum) ou en décimale ne vous aide pas.

2
devio

Si vous utilisez une fonction CLR, vous pouvez convertir le float en une chaîne qui ressemble à celle-ci, sans les 0 supplémentaires à la fin.

Fonction CLR

[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
[return: SqlFacet(MaxSize = 50)]
public static SqlString float_to_str(double Value, int TruncAfter)
{
  string rtn1 = Value.ToString("R");
  string rtn2 = Value.ToString("0." + new string('0', TruncAfter));

  if (rtn1.Length < rtn2.Length) { return rtn1; } else { return rtn2; }
}

.

Exemple

create table #temp (value float)
insert into #temp values (0.73), (0), (0.63921), (-0.70945), (0.28), (0.72000002861023), (3.7), (-0.01), (0.86), (0.55489), (0.439999997615814)

select value,
       dbo.float_to_str(value, 18) as converted,
       case when value = cast(dbo.float_to_str(value, 18) as float) then 1 else 0 end as same
from   #temp

drop table #temp

.

Sortie

value                  converted                  same
---------------------- -------------------------- -----------
0.73                   0.73                       1
0                      0                          1
0.63921                0.63921                    1
-0.70945               -0.70945                   1
0.28                   0.28                       1
0.72000002861023       0.72000002861023           1
3.7                    3.7                        1
-0.01                  -0.01                      1
0.86                   0.86                       1
0.55489                0.55489                    1
0.439999997615814      0.439999997615814          1

.

Caveat

Toutes les chaînes converties sont tronquées à 18 décimales et il n'y a pas de zéros à la fin. La précision à 18 chiffres n’est pas un problème pour nous. De plus, 100% de nos numéros FP (près de 100 000 valeurs) ont la même forme que les valeurs de chaîne, comme dans la base de données, sous forme de nombres FP.

1
James L.

Essayez celui-ci, devrait fonctionner:

cast((convert(bigint,b.tax_id)) as varchar(20))
1
Kam
select replace(myFloat, '', '')

de REPLACE () documentation :

Renvoie nvarchar si l'un des arguments d'entrée est du type de données nvarchar. sinon, REPLACE renvoie varchar.
Renvoie NULL si l'un des arguments est NULL.

tests:
null ==> [NULL]
1.11 ==> 1.11
1.10 ==> 1.1
1,00 ==> 1
0.00 ==> 0
- 1.10 ==> -1.1
0,00001 ==> 1e-005
0.000011 ==> 1.1e-005

0
Dinah

Je viens de rencontrer une situation similaire et j'ai été surpris par l'arrondi des problèmes de «très grand nombre» présenté dans SSMS v17.9.1/SQL 2017.

Je ne suggère pas d’avoir une solution, mais j’ai observé que FORMATprésente un nombre qui semble correct. Je ne peux pas en déduire que cela réduit les problèmes d'arrondis ou est utile dans le cadre d'une fonction mathématique complexe.

Le code SQL fourni qui devrait démontrer clairement mes observations tout en permettant à d’autres de tester leur code et leurs idées le cas échéant. 

WITH Units AS 
(
   SELECT 1.0 AS [RaisedPower] , 'Ten' As UnitDescription
   UNION ALL
   SELECT 2.0 AS [RaisedPower] , 'Hundred' As UnitDescription
   UNION ALL
   SELECT 3.0 AS [RaisedPower] , 'Thousand' As UnitDescription
   UNION ALL
   SELECT 6.0 AS [RaisedPower] , 'Million' As UnitDescription
   UNION ALL
   SELECT 9.0 AS [RaisedPower] , 'Billion' As UnitDescription
   UNION ALL
   SELECT 12.0 AS [RaisedPower] , 'Trillion' As UnitDescription
   UNION ALL
   SELECT 15.0 AS [RaisedPower] , 'Quadrillion' As UnitDescription
   UNION ALL
   SELECT 18.0 AS [RaisedPower] , 'Quintillion' As UnitDescription
   UNION ALL
   SELECT 21.0 AS [RaisedPower] , 'Sextillion' As UnitDescription
   UNION ALL
   SELECT 24.0 AS [RaisedPower] , 'Septillion' As UnitDescription
   UNION ALL
   SELECT 27.0 AS [RaisedPower] , 'Octillion' As UnitDescription
   UNION ALL
   SELECT 30.0 AS [RaisedPower] , 'Nonillion' As UnitDescription
   UNION ALL
   SELECT 33.0  AS [RaisedPower] , 'Decillion' As UnitDescription

)

SELECT UnitDescription

   ,              POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )                                                             AS ReturnsFloat
   ,        CAST( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )  AS NUMERIC (38,0) )                                        AS RoundingIssues
   , STR(   CAST( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )  AS NUMERIC (38,0) ) ,   CAST([RaisedPower] AS INT) + 2, 0) AS LessRoundingIssues
   , FORMAT(      POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )  , '0')                                                     AS NicelyFormatted

FROM Units
ORDER BY [RaisedPower]
0
Andrew

La réponse d'Axel modifiée un peu, car dans certains cas, elle produira des résultats indésirables.

DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;

SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM((REPLACE(CAST(CAST(@MyFloat AS DECIMAL(38,18)) AS VARCHAR(max)), '0', ' '))), ' ', '0'),'.',' ')),' ','.')
0
user2388752

Sélectionner
cast (replace (convert (décimal (15,2), acs_daily_debit), '.', ',') comme varchar (20))

de acs_balance_details

0
Eduardo

Basé sur la réponse moléculaire:

DECLARE @F FLOAT = 1000000000.1234;
SELECT @F AS Original, CAST(FORMAT(@F, N'#.##############################') AS VARCHAR) AS Formatted;

SET @F = 823399066925.049
SELECT @F AS Original, CAST(@F AS VARCHAR) AS Formatted
UNION ALL SELECT @F AS Original, CONVERT(VARCHAR(128), @F, 128) AS Formatted
UNION ALL SELECT @F AS Original, CAST(FORMAT(@F, N'G') AS VARCHAR) AS Formatted;

SET @F = 0.502184537571209
SELECT @F AS Original, CAST(@F AS VARCHAR) AS Formatted
UNION ALL SELECT @F AS Original, CONVERT(VARCHAR(128), @F, 128) AS Formatted
UNION ALL SELECT @F AS Original, CAST(FORMAT(@F, N'G') AS VARCHAR) AS Formatted;
0
user8642458