Conversion de type de données

Dans de nombreux cas, une valeur d’un type de données peut être convertie en un autre type de données. Par exemple, un INTEGER peut être converti en un type de données à virgule flottante. La conversion d’un type de données est appelée casting.

Dans ce chapitre :

Casting explicite vs. casting implicite

Les utilisateurs peuvent convertir explicitement une valeur d’un type de données à un autre. C’est ce qu’on appelle le casting explicite.

Dans certaines situations, Snowflake convertit automatiquement une valeur en un autre type de données. C’est ce qu’on appelle le casting implicite ou la coercition.

Casting explicite

Les utilisateurs peuvent convertir explicitement une valeur en utilisant l’une des options suivantes :

  • La fonction CAST.

  • L’opérateur :: (appelé opérateur cast).

  • La fonction SQL appropriée (par exemple TO_DOUBLE).

Par exemple :

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

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

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

Le casting est autorisé dans la plupart des contextes dans lesquels une expression générale est autorisée, y compris la clause WHERE. Par exemple :

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

Casting implicite (« Coercition »)

La coercition se produit lorsqu’une fonction (ou un opérateur) requiert un type de données différent des arguments (ou opérandes), mais compatible avec ceux-ci.

  • Exemples de fonctions ou de procédures stockées :

    • Le code suivant convertit la valeur INTEGER de la colonne my_integer_column en FLOAT afin que cette valeur puisse être transmise à la fonction my_float_function(), qui attend un FLOAT :

      SELECT my_float_function(my_integer_column)
          FROM my_table;
      
      Copy
  • Exemples d’opérateurs :

    • Le code suivant convertit la valeur INTEGER 17 en VARCHAR afin que les valeurs puissent être concaténées en utilisant l’opérateur || :

      SELECT 17 || '76';
      
      Copy

      Le résultat de cette instruction SELECT est la chaîne '1776'.

    • L’instruction suivante convertit la valeur INTEGER de la colonne my_integer_column en FLOAT afin que cette valeur puisse être comparée à la valeur my_float_column à l’aide de l’opérateur de comparaison < :

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

Tous les contextes (par exemple, tous les opérateurs) ne prennent pas forcément en charge la coercition.

Casting et préséance

Lors d’un casting à l’intérieur d’une expression, le code doit tenir compte de la précédence de l’opérateur cast par rapport aux autres opérateurs de l’expression.

Prenons l’exemple suivant :

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

L’opérateur cast a une priorité plus élevée que l’opérateur arithmétique * (multiplier), donc l’instruction est interprétée comme suit :

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

Pour caster le résultat de l’expression height * width, utilisez les parenthèses, comme indiqué ci-dessous :

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

Par exemple également, considérons l’instruction suivante :

SELECT -0.0::FLOAT::BOOLEAN;
Copy

Vous pourriez vous attendre à ce que cela soit interprété comme suit :

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

et donc de retourner FALSE (0 = FALSE, 1 = TRUE).

Toutefois, l’opérateur cast a une priorité plus élevée que l’opérateur unaire moins (négation), si bien que l’instruction est interprétée comme suit :

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

et entraîne donc un message d’erreur, car le moins unaire ne peut pas être appliqué à un BOOLEAN.

Types de données pouvant être castés

La table ci-dessous indique les conversions de types de données valides dans Snowflake. La table indique également les coercitions que Snowflake peut effectuer automatiquement.

Note

En interne, la fonction CAST et l’opérateur :: appellent la fonction de conversion appropriée. Par exemple, si vous transformez un NUMBER en BOOLEAN, Snowflake appelle la fonction TO_BOOLEAN. Les notes sur l’utilisation pour chaque fonction de conversion s’appliquent lorsque la fonction est appelée indirectement par le biais d’une conversion, ainsi que lorsque la fonction est appelée directement. Par exemple, si vous exécutez CAST(my_decimal_column as BOOLEAN), les règles d’appel de TO_BOOLEAN avec une valeur DECIMAL s’appliquent. Pour plus de commodité, la colonne « Notes » du tableau ci-dessous comprend des liens vers les fonctions de conversion pertinentes.

Pour plus de détails sur les conversions entre les types semi-structurés et les types structurés, voir Conversion de types structurés et semi-structurés.

Type de données source

Type de données cible

Convertible

Coercitif

Fonction de conversion

Notes

ARRAY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

BINARY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

BOOLEAN

NUMBER

TO_NUMBER

VARCHAR

TO_VARCHAR

Par exemple, de TRUE à “true”.

VARIANT

TO_VARIANT

DATE

TIMESTAMP

TO_TIMESTAMP

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

FLOAT . (nombres à virgule flottante)

BOOLEAN

TO_BOOLEAN

Par exemple, de 0.0 à FALSE.

NUMBER[(p,s)]

TO_NUMBER

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

GEOGRAPHY

VARIANT

TO_VARIANT

GEOMETRY

VARIANT

TO_VARIANT

NUMBER[(p,s)] . (Nombres à virgule fixe, y compris INTEGER)

BOOLEAN

TO_BOOLEAN

Par exemple, de 0 à 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

Par exemple, de “false” à FALSE.

DATE

TO_DATE , DATE

FLOAT

TO_DOUBLE

Par exemple, de “12.34” à 12.34.

NUMBER[(p,s)]

TO_NUMBER

Par exemple, de “12.34” à 12.34.

TIME

TO_TIME , TIME

TIMESTAMP

TO_TIMESTAMP

VARIANT

TO_VARIANT

VARIANT

ARRAY

TO_ARRAY

BOOLEAN

TO_BOOLEAN

Par exemple, d’un VARIANT contenant “false” à 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 peut être converti en TIMESTAMP, car les valeurs sont traitées comme des secondes depuis le début de l’epoch (1970-01-01 00:00:00).

Remarques :

  • Pour chaque type de données répertorié (par exemple, FLOAT), les règles s’appliquent à tous les alias de ce type de données (par exemple, les règles pour FLOAT s’appliquent à DOUBLE, qui est un alias de FLOAT).

Notes sur l’utilisation

Sauf indication contraire, les règles suivantes s’appliquent à la fois au casting explicite et au casting implicite.

  • La conversion dépend non seulement du type de données, mais aussi de la valeur de la source. Par exemple :

    • Le VARCHAR “123” peut être converti en valeur numérique, ce qui n’est pas possible pour le VARCHAR “xyz”.

    • La possibilité de caster une valeur spécifique de type VARIANT dépend du type des données à l’intérieur des VARIANT. Par exemple, si le VARIANT contient une valeur de type TIME, vous ne pouvez pas caster le VARIANT en TIMESTAMP, car vous ne pouvez pas convertir TIME en TIMESTAMP.

  • Si possible, transmettez des arguments du même type. Évitez de transmettre des arguments de types différents.

  • Si l’un des arguments est un nombre, la fonction contraint les arguments de type chaîne non numérique (par exemple 'a string') et les arguments de type chaîne qui ne sont pas des constantes au type NUMBER(18,5).

    Pour les arguments numériques de type chaîne qui ne sont pas des constantes, si NUMBER(18,5) n’est pas suffisant pour représenter la valeur numérique, vous devez convertir l’argument en un type qui peut représenter la valeur.

  • Pour certaines paires de types de données, la conversion peut entraîner une perte de précision. Par exemple :

    • La conversion de FLOAT en INTEGER arrondit la valeur.

    • La conversion d’une valeur numérique à virgule fixe (par exemple, NUMBER(38, 0)) en valeur à virgule flottante (par exemple, FLOAT) peut entraîner un arrondi ou une troncation si le nombre à virgule fixe ne peut pas être représenté précisément dans un nombre à virgule flottante.

    • La conversion d’un TIMESTAMP en DATE supprime les informations relatives à l’heure de la journée.

  • Bien que Snowflake convertisse les valeurs dans certaines situations où une perte de précision peut se produire, Snowflake ne permet pas la conversion dans d’autres situations où une perte de précision se produirait. Par exemple, Snowflake n’autorise pas la conversion lorsqu’une conversion permettrait de :

    • Tronquer une valeur VARCHAR. Par exemple, Snowflake ne convertit pas VARCHAR(10) en VARCHAR(5), que ce soit de façon implicite ou explicite.

    • Entraîner la perte de chiffres autres que les chiffres les moins significatifs. Par exemple, ce qui suit échoue :

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

    Dans cet exemple, le nombre 12.3 comporte deux chiffres avant la virgule, mais le type de données NUMBER(3,2) ne peut contenir qu’un seul chiffre avant la virgule.

  • Lors de la conversion d’un type avec moins de précision vers un type avec plus de précision, la conversion utilise des valeurs par défaut. Par exemple, la conversion d’un DATE en un TIMESTAMP_NTZ fait en sorte que l’heure, la minute, la seconde et les fractions de seconde soient définies sur 0.

  • Lorsqu’une valeur FLOAT est convertie en VARCHAR, les zéros de fin sont omis.

    Par exemple, les instructions suivantes créent une table et insèrent une ligne qui contient un VARCHAR, un FLOAT et un VARIANT. Le VARIANT est construit à partir du JSON qui contient une valeur à virgule flottante représentée par des zéros de fin.

    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

    L’instruction SELECT suivante remplace explicitement la colonne FLOAT et la valeur FLOAT de la colonne VARIANT par VARCHAR. Dans chaque cas, le VARCHAR ne contient pas de zéros de fin :

    select varchar1, 
           float1::varchar,
           variant1:"Loan Number"::varchar from tmp;
    +----------+-----------------+---------------------------------+
    | VARCHAR1 | FLOAT1::VARCHAR | VARIANT1:"LOAN NUMBER"::VARCHAR |
    |----------+-----------------+---------------------------------|
    | 5.000    | 5               | 5                               |
    +----------+-----------------+---------------------------------+
    
    Copy
  • Certaines opérations peuvent renvoyer différents types de données, en fonction d’une expression conditionnelle. Par exemple, les appels COALESCE suivants renvoient des types de données légèrement différents selon les valeurs d’entrée :

    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

    Si l’expression a plus d’un type de données possible, Snowflake choisit le type de données en fonction du résultat réel. (Pour plus d’informations sur la précision et l’échelle dans les calculs, voir Échelle et précision dans les opérations arithmétiques). Si la requête génère plus d’un résultat (par exemple, plusieurs lignes de résultats), Snowflake choisit un type de données capable de contenir chacun des résultats individuels.

  • Certains programmes d’application, tels que SnowSQL, et certaines interfaces utilisateur graphiques, telles que l”Classic Console, appliquent leurs propres règles de conversion et de formatage lors de l’affichage des données. Par exemple, SnowSQL affiche les valeurs BINARY sous la forme d’une chaîne qui ne contient que des chiffres hexadécimaux ; cette chaîne est générée en appelant implicitement une fonction de conversion. Par conséquent, les données que SnowSQL affiche peuvent ne pas indiquer sans ambiguïté quelles conversions de données Snowflake a forcées.