CAST e conversão de tipos

1. Introdução à Conversão de Tipos no SQL

A conversão de tipos no SQL é o processo de transformar um valor de um tipo de dado para outro. Essa operação é fundamental quando precisamos comparar, combinar ou armazenar dados que originalmente estão em formatos incompatíveis.

Existem duas formas de conversão:

  • Conversão implícita: ocorre automaticamente pelo banco de dados quando os tipos são compatíveis. Exemplo: SELECT 5 + '3' — o banco converte a string '3' para inteiro automaticamente.

  • Conversão explícita: é feita manualmente pelo desenvolvedor usando funções como CAST ou operadores específicos. Exemplo: SELECT CAST('123' AS INTEGER).

Os tipos de dados mais comuns que exigem conversão incluem:
- INTEGER (números inteiros)
- VARCHAR / CHAR (texto)
- DATE / TIMESTAMP (datas e horários)
- NUMERIC / DECIMAL (números com precisão decimal)

2. A Função CAST: Sintaxe e Uso Básico

A função CAST segue a sintaxe padrão ANSI SQL:

CAST(expressão AS tipo_destino)

Exemplo 1 — Convertendo texto para número:

SELECT CAST('150' AS INTEGER) AS numero;
-- Resultado: 150

Exemplo 2 — Convertendo número para texto:

SELECT CAST(12345 AS VARCHAR(10)) AS texto;
-- Resultado: '12345'

Exemplo 3 — Convertendo data para string:

SELECT CAST(CURRENT_DATE AS VARCHAR(10)) AS data_texto;
-- Resultado: '2025-03-15' (formato dependente do banco)

Exemplo 4 — Convertendo string para data:

SELECT CAST('2025-12-25' AS DATE) AS natal;
-- Resultado: 2025-12-25 (tipo DATE)

3. Operador :: (Shorthand) no PostgreSQL

O PostgreSQL oferece uma sintaxe alternativa usando dois-pontos duplos (::), que é mais concisa e amplamente utilizada:

expressão::tipo_destino

Comparação entre CAST e :::

-- Usando CAST (padrão ANSI)
SELECT CAST('3.14' AS NUMERIC(4,2));

-- Usando :: (PostgreSQL)
SELECT '3.14'::NUMERIC(4,2);
-- Ambos retornam: 3.14

Exemplos práticos com :::

-- Texto para inteiro
SELECT '42'::INTEGER;

-- Inteiro para texto
SELECT 99::TEXT;

-- Data para timestamp
SELECT '2025-01-01'::DATE::TIMESTAMP;

Em termos de performance, ambos são equivalentes. A escolha entre CAST e :: depende da portabilidade desejada. CAST é padrão ANSI e funciona em todos os bancos; :: é específico do PostgreSQL, porém mais legível e rápido de escrever.

4. Conversão entre Tipos Numéricos

Convertendo INTEGER para DECIMAL/NUMERIC:

SELECT CAST(7 AS NUMERIC(10,2)) AS valor;
-- Resultado: 7.00

Arredondamento e truncamento com CAST:

-- Convertendo DECIMAL para INTEGER (trunca a parte decimal)
SELECT CAST(9.87 AS INTEGER);
-- Resultado: 9 (truncado, não arredondado)

-- Para arredondar, use ROUND antes do CAST
SELECT CAST(ROUND(9.87) AS INTEGER);
-- Resultado: 10

Cuidados com perda de precisão em conversões de FLOAT para INTEGER:

-- Conversão de FLOAT para INTEGER pode causar erro de arredondamento
SELECT CAST(123456789.12 AS FLOAT) AS float_valor;
SELECT CAST(123456789.12 AS INTEGER);
-- Perde a parte decimal e pode apresentar imprecisões em números muito grandes

5. Conversão de Datas e Horários

Convertendo strings no formato 'YYYY-MM-DD' para DATE:

SELECT CAST('2025-06-15' AS DATE) AS data_formatada;
-- Funciona corretamente pois o formato é ISO 8601

Usando CAST com TIMESTAMP e TIME:

-- String para TIMESTAMP
SELECT CAST('2025-06-15 14:30:00' AS TIMESTAMP) AS data_hora;

-- String para TIME
SELECT CAST('14:30:00' AS TIME) AS hora;

Erros comuns com formatos inválidos:

-- Formato inválido (mês antes do dia)
SELECT CAST('15/06/2025' AS DATE);
-- ERRO: formato de data inválido

-- Solução: usar formato ISO ou função específica
SELECT CAST('2025-06-15' AS DATE); -- Correto

6. Conversão de Tipos de Texto

VARCHAR para CHAR e vice-versa:

-- VARCHAR para CHAR (completa com espaços)
SELECT CAST('abc' AS CHAR(5));
-- Resultado: 'abc  ' (espaços à direita)

-- CHAR para VARCHAR (remove espaços)
SELECT CAST('abc  ' AS VARCHAR(5));
-- Resultado: 'abc' (espaços removidos)

Convertendo texto para BOOLEAN:

-- No PostgreSQL
SELECT 'true'::BOOLEAN;  -- Retorna TRUE
SELECT 'false'::BOOLEAN; -- Retorna FALSE
SELECT '1'::BOOLEAN;     -- Retorna TRUE
SELECT '0'::BOOLEAN;     -- Retorna FALSE

Tratamento de espaços e caracteres especiais:

-- Espaços extras podem causar erro na conversão
SELECT CAST('  123  ' AS INTEGER);
-- Pode falhar em alguns bancos; use TRIM primeiro

SELECT CAST(TRIM('  123  ') AS INTEGER);
-- Resultado: 123

7. Tratamento de Erros e Nulos em Conversões

O que acontece quando o CAST falha:

-- Conversão inválida gera erro
SELECT CAST('abc' AS INTEGER);
-- ERRO: valor inválido para tipo INTEGER

Usando TRY_CAST (SQL Server):

-- TRY_CAST retorna NULL em vez de erro
SELECT TRY_CAST('abc' AS INTEGER);
-- Resultado: NULL (sem erro)

SELECT TRY_CAST('123' AS INTEGER);
-- Resultado: 123

Combinação com COALESCE para valores nulos:

-- Se a conversão falhar, usa um valor padrão
SELECT COALESCE(TRY_CAST('abc' AS INTEGER), 0) AS valor_seguro;
-- Resultado: 0 (valor padrão)

Alternativa no PostgreSQL com blocos de erro:

-- Usando CASE e validação
SELECT 
  CASE 
    WHEN 'abc' ~ '^[0-9]+$' THEN 'abc'::INTEGER
    ELSE NULL
  END AS valor_validado;

8. Boas Práticas e Performance

Quando usar CAST vs. funções específicas:

  • Use CAST para conversões simples e portabilidade entre bancos.
  • Use funções específicas (TO_DATE, TO_NUMBER) quando precisar de controle fino sobre formatos.
-- TO_DATE permite especificar formato
SELECT TO_DATE('15/06/2025', 'DD/MM/YYYY');

-- Equivalente com CAST (formato ISO)
SELECT CAST('2025-06-15' AS DATE);

Impacto no desempenho:

Conversões excessivas em cláusulas WHERE e JOIN podem impedir o uso de índices:

-- Ruim: converte a coluna, impedindo uso de índice
SELECT * FROM vendas 
WHERE CAST(data_venda AS VARCHAR) = '2025-03-15';

-- Bom: compara diretamente com o tipo correto
SELECT * FROM vendas 
WHERE data_venda = CAST('2025-03-15' AS DATE);

Dicas para evitar conversões desnecessárias:

  1. Mantenha os tipos consistentes entre colunas relacionadas.
  2. Evite CAST em colunas indexadas dentro de WHERE.
  3. Prefira parâmetros tipados em consultas preparadas.
  4. Use TRY_CAST ou validação prévia em cenários com dados imprevisíveis.
  5. Documente conversões complexas para facilitar manutenção.

Referências