Como converter float para varchar no SQL Server

Eu tenho uma coluna de flutuação com números de comprimento diferente e estou tentando convertê-los em varchar.

Alguns valores excedem o tamanho máximo do bigint, por isso não posso fazer algo como isto

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

Eu tentei usar decimal, mas os números não são do mesmo tamanho, então isso não ajuda muito

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

Qualquer ajuda é apreciada.

ATUALIZAR:

O valor da amostra é 2.2000012095022E + 26 .

Tente usar a function STR() .

 SELECT STR(float_field, 25, 5) 

Função STR ()


Outra nota: esta almofada à esquerda com espaços. Se isso for um problema, combine com o LTRIM :

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

O único bit de consulta que eu encontrei que retorna o mesmo número original EXATO é

 CONVERT (VARCHAR(50), float_field,128) 

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

As outras soluções acima, às vezes, arredondam ou adicionam dígitos no final

ATUALIZAÇÃO : conforme comentários abaixo e o que eu posso ver em https://msdn.microsoft.com/en-us/library/ms187928.aspx :

 CONVERT (VARCHAR(50), float_field,3) 

Deve ser usado em novas versões do SQL Server (Banco de Dados SQL do Azure e iniciando no SQL Server 2016 RC3)

essa é a solução que acabei usando no sqlserver 2012 (já que todas as outras sugestões tinham a desvantagem de truncar partes fracionárias ou alguma outra desvantagem).

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

saída:

 1000000000.1234 

isso tem a vantagem adicional (no meu caso) de tornar o separador e a localização de milhares fácil:

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

saída:

 1.000.000.000,1234 

Converta em um integer primeiro e depois em uma string :

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

float só tem um max. precisão de 15 dígitos. Dígitos após a 15ª posição são, portanto, randoms e a conversão para bigint (máx. 19 dígitos) ou decimal não ajuda você.

Tópico útil obrigado.

Se você quiser, como eu remover leadings zero você pode usar isso:

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

Isso pode ajudar sem arredondar

 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) 

Se você usa uma function CLR, você pode converter o float em uma string parecida com a float, sem todos os 0s extras no final.

Função 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; } } 

.

Exemplo

 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 

.

Saída

 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 

.

Embargo

Todas as cadeias convertidas são truncadas em 18 casas decimais e não há zeros à direita. 18 dígitos de precisão não são um problema para nós. E, 100% dos nossos números de FP (perto de 100.000 valores) parecem idênticos aos valores de string, como fazem no database como números FP.

A resposta modificada do Axel, como em certos casos, produzirá resultados indesejáveis.

 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'),'.',' ')),' ','.') 
 select replace(myFloat, '', '') 

da documentação de REPLACE () :

Retorna nvarchar se um dos argumentos de input for do tipo de dados nvarchar; Caso contrário, REPLACE retornará varchar.
Retorna NULL se algum dos argumentos for NULL.

testes:
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

Selecione
cast (replace (converter (decimal (15,2), acs_daily_debit), ‘.’, ‘,’) como varchar (20))

de acs_balance_details

Tente este aqui, deve funcionar:

 cast((convert(bigint,b.tax_id)) as varchar(20)) 

Baseado na resposta molecular:

 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; 

Acabei de me deparar com uma situação semelhante e fiquei surpreendido com os problemas de arredondamento de ‘números muito grandes’ apresentados no SSMS v17.9.1 / SQL 2017.

Não estou sugerindo que tenho uma solução, mas observei que o FORMAT apresenta um número que parece correto. Eu não posso implicar que isso reduz mais problemas de arredondamento ou é útil dentro de uma function matemática complicada.

T SQL Code fornecido, que deve demonstrar claramente minhas observações, permitindo que outros testem seu código e idéias, se necessário.

 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]