Neste post de hoje eu gostaria de mostrar pra vocês a função T-SQL FORMAT, disponível desde o SQL Server 2012, e que até hoje pouca gente utiliza no dia a dia para formatação de datas e números.
Quando vou analisar queries, funções e Stored Procedures, vejo que ainda hoje, vários desenvolvedores insistem em utilizar CAST, CONVERT e concatenações para formatar datas e números, mesmo com uma função especificamente para isso. Após ler esse post, espero que você entenda como utilizar essa função e comece a simplificar seus códigos T-SQL com ela.
Quem nunca precisou preencher um número com 0 à esquerda para gerar layout? Formatar uma data? Extrair somente a hora de uma data? São inúmeras situações em que a função FORMAT é útil.
Formatando dados numéricos
Formatação Pré-definida
Uso mais simples, as funções pré-definidas permitem a formatação de valores utilizando máscaras já definidas por padrão no SQL Server, como “C” para modela (currency).
Formatos mais utilizados
SELECT
FORMAT(123456.99, 'C'), -- Formato de moeda padrão
FORMAT(-123456.987654321, 'C4'), -- Formato de moeda com 4 casas decimais
FORMAT(123456.987654321, 'C2', 'pt-br') -- Formato de moeda forçando a localidade pra Brasil e 2 casas decimais
SELECT
FORMAT(123456.99, 'D'), -- Formato de número inteiro com valores numeric (NULL)
FORMAT(123456, 'D'), -- Formato de número inteiro
FORMAT(-123456, 'D4'), -- Formato de número inteiro com valores negativos
FORMAT(123456, 'D10', 'pt-br'), -- formato de número inteiro com tamanho fixo em 10 caracteres
FORMAT(-123456, 'D10', 'pt-br') -- formato de número inteiro com tamanho fixo em 10 caracteres
SELECT
FORMAT(123456.99, 'E'), -- Formato de notação científica
FORMAT(123456.99, 'E4') -- Formato de notação científica e 4 casas decimais de precisão
SELECT
FORMAT(1, 'P'), -- Formato de porcentagem
FORMAT(1, 'P2'), -- Formato de porcentagem com 2 casas decimais
FORMAT(0.91, 'P'), -- Formato de porcentagem
FORMAT(0.005, 'P4') -- Formato de porcentagem com 4 casas decimais
SELECT
FORMAT(255, 'X'), -- Formato hexadecimal
FORMAT(512, 'X8') -- Formato hexadecimal fixando o retorno em 8 caracteres
Exemplos
Outros formatos
SELECT
FORMAT(123456.99, 'F'), -- Formato de número
FORMAT(123456.99, 'F4') -- Formato de número com 4 casas decimais
SELECT
FORMAT(123456.99, 'G'), -- Formato de número compacto
FORMAT(123456.99, 'G4'), -- Formato de número (tenta forçar o número com 4 caracteres)
FORMAT(123456.99, 'G20') -- Formato de número com tamanho máximo de 10 caracteres
SELECT
FORMAT(123456.99, 'N'), -- Formato de número genérico
FORMAT(123456.99, 'N4') -- Formato de número genérico fixando 4 casas decimais
Exemplos
Formatação Personalizada
Preenchendo um número com zero à esquerda
Formatando um número para moeda brasileira
Função utilizada nesse exemplo:
CREATE FUNCTION fncConverte_Moeda_Real (
@Numero VARCHAR(40)
)
RETURNS VARCHAR(40)
AS
BEGIN
DECLARE @Contador INT
DECLARE @Pontos INT
DECLARE @CasasVirgula INT
DECLARE @Parte1 VARCHAR(40)
DECLARE @Parte2 VARCHAR(40)
SET @CasasVirgula = (LEN(SUBSTRING(@Numero, CHARINDEX('.', @Numero) + 1, LEN(@Numero))))
IF @CasasVirgula > 2
SET @Numero = (SUBSTRING(@Numero, 1, (CHARINDEX('.', @Numero)) + 2))
IF CHARINDEX('.', @Numero) <> 0 BEGIN
SET @Numero = REPLACE(@Numero, '.', ',')
IF LEN(SUBSTRING(@Numero, CHARINDEX(',', @Numero) + 1, 2)) = 1
SET @Numero = @Numero + '0'
END
ELSE
SET @Numero = @Numero + ',00'
SET @Contador = (CHARINDEX(',', @Numero) - 1)
SET @Pontos = @Contador / 3
WHILE @Pontos <> 0 BEGIN
SET @Contador = @Contador - 3
SET @Parte2 = (SUBSTRING(@Numero, @Contador + 1, LEN(@Numero)))
SET @Parte1 = (SUBSTRING(@Numero, 1, (CHARINDEX(@Parte2, @Numero) - 1)))
SET @Numero = @Parte1 + '.' + @Parte2
SET @Pontos = @Pontos - 1
END
IF (SUBSTRING(@Numero, 1, 1)) = '.'
SET @Numero = (SUBSTRING(@Numero, 2, LEN(@Numero)))
SET @Numero = 'R$ ' + @Numero
RETURN @Numero
END
Outros exemplos:
SELECT
-- Formato de moeda brasileira (manualmente)
FORMAT(123456789.9, 'R$ ###,###,###,###.00'),
-- Utilizando sessão (;) para formatar valores positivos e negativos
FORMAT(123456789.9, 'R$ ###,###,###,###.00;-R$ ###,###,###,###.00'),
-- Utilizando sessão (;) para formatar valores positivos e negativos
FORMAT(-123456789.9, 'R$ ###,###,###,###.00;-R$ ###,###,###,###.00'),
-- Utilizando sessão (;) para formatar valores positivos e negativos
FORMAT(-123456789.9, 'R$ ###,###,###,###.00;(R$ ###,###,###,###.00)'),
-- Formatando porcentagem com 2 casas decimais
FORMAT(0.9975, '#.00%'),
-- Formatando porcentagem com 4 casas decimais
FORMAT(0.997521654, '#.0000%'),
-- Formatando porcentagem com 4 casas decimais
FORMAT(123456789.997521654, '#.0000%'),
-- Formatando porcentagem com 2 casas decimais e utilizando sessão (;)
FORMAT(0.123456789, '#.00%;-#.00%'),
-- Formatando porcentagem com 2 casas decimais e utilizando sessão (;)
FORMAT(-0.123456789, '#.00%;-#.00%'),
-- Formatando porcentagem com 2 casas decimais e utilizando sessão (;)
FORMAT(-0.123456789, '#.00%;(#.00%)')
Resultado:
Formatando datas
Formatação Pré-definida
Formatos mais comuns
SET LANGUAGE 'English'
SELECT
FORMAT(GETDATE(), 'd'), -- Padrão de data abreviada.
FORMAT(GETDATE(), 'D'), -- Padrão de data completa.
FORMAT(GETDATE(), 'R'), -- Padrão RFC1123
FORMAT(GETDATE(), 't'), -- Padrão de hora abreviada.
FORMAT(GETDATE(), 'T') -- Padrão de hora completa.
SET LANGUAGE 'Brazilian'
SELECT
FORMAT(GETDATE(), 'd'), -- Padrão de data abreviada.
FORMAT(GETDATE(), 'D'), -- Padrão de data completa.
FORMAT(GETDATE(), 'R'), -- Padrão RFC1123
FORMAT(GETDATE(), 't'), -- Padrão de hora abreviada.
FORMAT(GETDATE(), 'T') -- Padrão de hora completa.
SELECT
-- Formato de data típico do Brasil
FORMAT(GETDATE(), 'dd/MM/yyyy'),
-- Formato de data/hora típico dos EUA
FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss.fff'),
-- Exibindo a data por extenso
FORMAT(GETDATE(), 'dddd, dd \d\e MMMM \d\e yyyy'),
-- Exibindo a data por extenso (forçando o idioma pra PT-BR)
FORMAT(GETDATE(), 'dddd, dd \d\e MMMM \d\e yyyy', 'pt-br'),
-- Exibindo a data/hora, mas zerando os minutos e segundos
FORMAT(GETDATE(), 'dd/MM/yyyy HH:00:00', 'pt-br')
Formatando números e datas antes do SQL Server 2012
Agora que vocês viram como é simples e rápido formatar números e datas utilizando a função nativa FORMAT, fica até difícil querer voltar a formatar esses tipos de dados manualmente, correto?
Infelizmente, a função FORMAT foi introduzida no SQL Server 2012, ou seja, nas versões 2005 e 2008, você ainda terá que utilizar as formas tradicionais (custosas e trabalhosas) de formatação de datas e números. Ou não.
Para quem tem um database project na sua instância (também conhecido como SQLCLR), você pode facilmente implementar 2 funções muito similares (praticamente iguais) a função FORMAT, permitindo que você possa formatar dados facilmente utilizando essas funções, mesmo nas versões 2005 e 2008 do SQL Server.
Vejam como a utilização é praticamente igual ao da função FORMAT (Não implementei o terceiro parâmetro – culture):
Reparem que, tanto os formatos pré-definidos quantos os formatos personalizados permanecem inalterados utilizando a função do CLR. Isso acontece porque a função FORMAT utiliza internamente, a mesma função do C# que utilizei nessas funções do SQLCLR.
Código-fonte da fncFormata_Datetime
using System.Data.SqlTypes;
using System.Globalization;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString fncFormata_Datetime(SqlDateTime Dt_Referencia, SqlString Ds_Mascara)
{
return Dt_Referencia.IsNull ? SqlString.Null : Dt_Referencia.Value.ToString(Ds_Mascara.Value, new CultureInfo("pt-BR"));
}
};
Como formatar números com o CLR
Exemplos com formatos padrão
Exemplos com formatos personalizados
Código-fonte da fncFormata_Numero
using System.Data.SqlTypes;
using System.Globalization;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString fncFormata_Numero(SqlDouble Ds_String, SqlString Ds_Formato)
{
if (Ds_String.IsNull)
return SqlString.Null;
return Ds_Formato.IsNull ? Ds_String.Value.ToString(CultureInfo.InvariantCulture) : Ds_String.Value.ToString(Ds_Formato.Value, CultureInfo.CreateSpecificCulture("pt-br"));
}
}
É isso aí, pessoal!
Espero que vocês passem a utilizar mais a função FORMAT no dia a dia de vocês (quando necessário) e caso estejam utilizando as versões 2005 ou 2008 do SQL Server, saibam que é possível simular o comportamento dessa função utilizando o SQLCLR.
Comentários (0)
Carregando comentários…