Conversão do tipo de dados

Em muitos casos, um valor de um tipo de dados pode ser convertido em outro tipo de dados. Por exemplo, um INTEGER pode ser convertido em um tipo de dados de ponto flutuante. A conversão de um tipo de dados é chamada de conversão (casting).

Neste tópico:

Conversão explícita vs. Conversão implícita

Os usuários podem converter explicitamente um valor de um tipo de dados em outro. Isto é chamado de conversão explícita.

Em algumas situações, o Snowflake converte automaticamente um valor em outro tipo de dados. Isto é chamado de conversão implícita ou coerção.

Conversão explícita

Os usuários podem converter um valor explicitamente usando qualquer uma das seguintes opções:

  • A função CAST.

  • O operador :: (chamado de operador de conversão).

  • A função SQL apropriada (por exemplo, TO_DOUBLE).

Por exemplo:

SELECT CAST('2022-04-01' AS DATE);

SELECT '2022-04-01'::DATE;

SELECT TO_DATE('2022-04-01');
Copy

A conversão é permitida na maioria dos contextos nos quais uma expressão geral é permitida, incluindo a cláusula WHERE. Por exemplo:

SELECT date_column
    FROM log_table
    WHERE date_column >= '2022-04-01'::DATE;
Copy

Conversão implícita (“coerção”)

A coerção ocorre quando uma função (ou operador) requer um tipo de dados diferente, mas compatível com os argumentos (ou operandos).

  • Exemplos para funções ou procedimentos armazenados:

    • O seguinte código aplica a coerção ao valor INTEGER na coluna my_integer_column para convertê-lo em FLOAT, de modo que o valor possa ser passado para a função my_float_function(), que espera um FLOAT:

      SELECT my_float_function(my_integer_column)
          FROM my_table;
      
      Copy
  • Exemplos para operadores:

    • O código a seguir aplica a coerção ao valor INTEGER 17 para convertê-lo em VARCHAR, de modo que os valores possam ser concatenados usando o operador ||:

      SELECT 17 || '76';
      
      Copy

      O resultado dessa instrução SELECT é a cadeia de caracteres '1776'.

    • A seguinte instrução aplica coerção ao valor INTEGER na coluna my_integer_column para convertê-lo em FLOAT, de modo que o valor possa ser comparado com o valor my_float_column usando o operador de comparação <:

      SELECT ...
          FROM my_table
          WHERE my_integer_column < my_float_column;
      
      Copy

Nem todos os contextos (por exemplo, nem todos os operadores) oferecem suporte à coerção.

Conversão e precedência

Ao converter dentro de uma expressão, o código deve levar em conta a precedência do operador de conversão em relação aos outros operadores da expressão.

Considere o seguinte exemplo:

SELECT height * width::VARCHAR || " square meters"
    FROM dimensions;
Copy

O operador de conversão tem maior precedência do que o operador aritmético * (multiplicar), portanto a instrução é interpretada como:

... height * (width::VARCHAR) ...
Copy

Para converter o resultado da expressão height * width, use parênteses, como mostrado abaixo:

SELECT (height * width)::VARCHAR || " square meters"
    FROM dimensions;
Copy

Como outro exemplo, considere a seguinte instrução:

SELECT -0.0::FLOAT::BOOLEAN;
Copy

É de se esperar que isto seja interpretado como:

SELECT (-0.0::FLOAT)::BOOLEAN;
Copy

e, portanto, retornar FALSE (0 = FALSE, 1 = TRUE).

Entretanto, o operador de conversão tem maior precedência do que o operador de menos unário (negação), portanto, a instrução é interpretada como:

SELECT -(0.0::FLOAT::BOOLEAN);
Copy

e, portanto, resulta em uma mensagem de erro porque o operador de menos unário não pode ser aplicado a um BOOLEAN.

Tipos de dados que podem ser convertidos

A tabela abaixo mostra as conversões de tipos de dados válidas no Snowflake. A tabela também mostra quais coerções o Snowflake pode executar automaticamente.

Nota

Internamente, a função CAST e o operador :: chamam a função de conversão apropriada. Por exemplo, se você converter um NUMBER em um BOOLEAN, o Snowflake chama a função TO_BOOLEAN. As notas de uso para cada função de conversão aplicam-se quando a função é chamada indiretamente por meio de uma conversão, bem como quando a função é chamada diretamente. Por exemplo, se você executar CAST(my_decimal_column as BOOLEAN), as regras para chamar TO_BOOLEAN com um valor DECIMAL se aplicam. Por conveniência, a coluna “Notas” na tabela abaixo inclui links para as funções de conversão relevantes.

Para obter detalhes sobre conversões entre tipos semiestruturados e tipos estruturados, consulte Conversão de tipos estruturados e semiestruturados.

Tipo de dados de origem

Tipo de dados de destino

Conversível

Coercível

Função de conversão

Notas

ARRAY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

BINARY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

BOOLEAN

NUMBER

TO_NUMBER

VARCHAR

TO_VARCHAR

Por exemplo, de TRUE para ‘true’.

VARIANT

TO_VARIANT

DATE

TIMESTAMP

TO_TIMESTAMP

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

FLOAT . (números de ponto flutuante)

BOOLEAN

TO_BOOLEAN

Por exemplo, de 0,0 para FALSE.

NUMBER[(p,s)]

TO_NUMBER

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

GEOGRAPHY

VARIANT

TO_VARIANT

GEOMETRY

VARIANT

TO_VARIANT

NUMBER[(p,s)] . (Números de ponto fixo, incluindo INTEGER)

BOOLEAN

TO_BOOLEAN

Por exemplo, de 0 para FALSE.

FLOAT

TO_DOUBLE

TIMESTAMP

TO_TIMESTAMP

1

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

OBJECT

ARRAY

TO_ARRAY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

TIME

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

TIMESTAMP

DATE

TO_DATE , DATE

TIME

TO_TIME , TIME

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

VARCHAR

BOOLEAN

TO_BOOLEAN

Por exemplo, de ‘false’ para FALSE.

DATE

TO_DATE , DATE

FLOAT

TO_DOUBLE

Por exemplo, de ‘12,34’ para 12,34.

NUMBER[(p,s)]

TO_NUMBER

Por exemplo, de ‘12,34’ para 12,34.

TIME

TO_TIME , TIME

TIMESTAMP

TO_TIMESTAMP

VARIANT

TO_VARIANT

VARIANT

ARRAY

TO_ARRAY

BOOLEAN

TO_BOOLEAN

Por exemplo, de um VARIANT contendo ‘false’ para FALSE.

DATE

TO_DATE , DATE

FLOAT

TO_DOUBLE

GEOGRAPHY

TO_GEOGRAPHY

NUMBER[(p,s)]

TO_NUMBER

OBJECT

TO_OBJECT

TIME

TO_TIME , TIME

TIMESTAMP

TO_TIMESTAMP

VARCHAR

TO_VARCHAR

1

NUMBER pode ser convertido em TIMESTAMP porque os valores são tratados como segundos desde o início da época (01-01-1970 00:00:00).

Notas:

  • Para cada tipo de dados listado (por exemplo, FLOAT), as regras se aplicam a todos os aliases para aquele tipo de dado (por exemplo, as regras para FLOAT se aplicam a DOUBLE, que é um alias para FLOAT).

Notas de uso

Exceto onde indicado de outra forma, as seguintes regras se aplicam tanto para conversão explícita quanto para conversão implícita.

  • A conversão depende não apenas do tipo de dados, mas também do valor de origem. Por exemplo:

    • O VARCHAR ‘123’ pode ser convertido em um valor numérico, mas o VARCHAR ‘xyz’ não pode ser convertido em um valor numérico.

    • A capacidade de converter um valor específico do tipo VARIANT depende do tipo dos dados dentro do VARIANT. Por exemplo, se o VARIANT contém um valor do tipo TIME, então não é possível converter a VARIANT em um TIMESTAMP porque não é possível converter TIME em TIMESTAMP.

  • Se possível, passe em argumentos do mesmo tipo. Evite passar em argumentos de diferentes tipos.

  • Se um dos argumentos for um número, a função aplica a coerção aos argumentos de cadeia de caracteres não numéricos (por exemplo, 'a string') e argumentos de cadeia de caracteres que não são constantes do tipo NUMBER(18,5).

    Para argumentos de cadeia de caracteres numérica que não são constantes, se NUMBER(18,5) não for suficiente para representar o valor numérico, você deve converter o argumento em um tipo que possa representar o valor.

  • Para alguns pares de tipos de dados, a conversão pode resultar em perda de precisão. Por exemplo:

    • A conversão de FLOAT em INTEGER arredonda o valor.

    • A conversão de um valor de ponto fixo numérico (por exemplo, NUMBER(38, 0)) em ponto flutuante (por exemplo, FLOAT) pode resultar em arredondamento ou truncamento se o número de ponto fixo não puder ser representado com precisão em um número de ponto flutuante.

    • A conversão de TIMESTAMP em DATE remove as informações sobre a hora do dia.

  • Embora o Snowflake converta valores em algumas situações em que pode haver perda de precisão, o Snowflake não permite a conversão em outras situações em que poderia ocorrer perda de precisão. Por exemplo, o Snowflake não permite a conversão quando a conversão:

    • Trunca um valor VARCHAR. Por exemplo, o Snowflake não converte VARCHAR(10) em VARCHAR(5), seja implícita ou explicitamente.

    • Resulta na perda de dígitos, exceto dígitos menos significativos. Por exemplo, o seguinte apresenta falha:

      select 12.3::FLOAT::NUMBER(3,2);
      
      Copy

    Neste exemplo, o número 12.3 tem dois dígitos antes do ponto decimal, mas o tipo de dados NUMBER(3,2) tem espaço para apenas um dígito antes do ponto decimal.

  • Ao converter de um tipo com menos precisão em um tipo com mais precisão, a conversão utiliza valores padrão. Por exemplo, a conversão de DATE em TIMESTAMP_NTZ faz com que a hora, o minuto, o segundo e os segundos fracionários sejam ajustados para 0.

  • Quando um valor FLOAT é convertido em VARCHAR, os zeros finais são omitidos.

    Por exemplo, as instruções a seguir criam uma tabela e inserem uma linha que contém um VARCHAR, um FLOAT e um VARIANT. O VARIANT é criado de um JSON que contém um valor de ponto flutuante representado com zeros finais.

    create or replace table tmp (
        varchar1 varchar, 
        float1 float, 
        variant1 variant
        );
    
    insert into tmp select '5.000', 5.000, parse_json('{"Loan Number": 5.000}');
    
    Copy

    A instrução SELECT a seguir converte explicitamente tanto a coluna FLOAT como o valor FLOAT dentro da coluna VARIANT em VARCHAR. Em cada caso, o VARCHAR não contém zeros finais:

    select varchar1, 
           float1::varchar,
           variant1:"Loan Number"::varchar from tmp;
    +----------+-----------------+---------------------------------+
    | VARCHAR1 | FLOAT1::VARCHAR | VARIANT1:"LOAN NUMBER"::VARCHAR |
    |----------+-----------------+---------------------------------|
    | 5.000    | 5               | 5                               |
    +----------+-----------------+---------------------------------+
    
    Copy
  • Algumas operações podem retornar diferentes tipos de dados, dependendo de uma expressão condicional. Por exemplo, as seguintes chamadas COALESCE retornam tipos de dados ligeiramente diferentes, dependendo dos valores de entrada:

    select system$typeof(ifnull(12.3, 0)),
           system$typeof(ifnull(NULL, 0));
    
    +--------------------------------+--------------------------------+
    | SYSTEM$TYPEOF(IFNULL(12.3, 0)) | SYSTEM$TYPEOF(IFNULL(NULL, 0)) |
    +--------------------------------+--------------------------------+
    | NUMBER(3,1)[SB1]               | NUMBER(1,0)[SB1]               |
    +--------------------------------+--------------------------------+
    
    Copy

    Se a expressão tiver mais de um tipo de dados possível, então o Snowflake escolhe o tipo de dados com base no resultado real. (Para obter mais informações sobre precisão e escala nos cálculos, consulte Escala e precisão em operações aritméticas). Se a consulta gerar mais de um resultado (por exemplo, várias linhas de resultados), o Snowflake escolhe um tipo de dados que é capaz de manter cada um dos resultados individuais.

  • Alguns programas de aplicativo, como o SnowSQL, e algumas interfaces gráficas de usuário, como o Classic Console, aplicam suas próprias regras de conversão e formatação ao exibir dados. Por exemplo, o SnowSQL exibe valores BINARY como uma cadeia de caracteres que contém apenas dígitos hexadecimais; essa cadeia é gerada pela chamada implícita de uma função de conversão. Portanto, os dados que o SnowSQL exibe podem não indicar inequivocamente a quais conversões de dados o Snowflake aplicou coerção.