# Types de données alternatifs

Le langage Data Shaping Query Language vous permet de gérer différents types de données pour un même élément, à l'aide d'un schéma Avro. Pour plus d'informations concernant les schémas Avro, consultez la [documentation Oracle](https://docs.oracle.com/cd/E26161_02/html/GettingStartedGuide/avroschemas.html) (en anglais).

Dans l'entrée JSON d'exemple suivante, l'élément order\_amount peut être :

* un entier
* un nombre décimal
* une chaîne de caractères
* un enregistrement contenant deux nombres décimaux, items\_total et tax\_amount

```
{
    "orders": [
        {
            "order_id": "abc-12345",
            "order_amount": 250
        },
        {
            "order_id": "def-67890",
            "order_amount": "299.99"
        },
        {
            "order_id": "ghi-54321",
            "order_amount": 435.95
        },
        {
            "order_id": "jkl-09876",
            "order_amount": {
                "items_total": 395.99,
                "tax_amount": 11.89
            }
        }
    ]
}
```

Cette entrée est décrite par le schéma Avro suivant :

```
{
    "type": "record",
    "name": "root",
    "fields": [
        {
            "name": "orders",
            "type": {
                "type": "array",
                "items": {
                    "type": "record",
                    "name": "order",
                    "fields": [
                        {
                            "name": "order_id",
                            "type": "string"
                        },
                        {
                            "name": "order_amount",
                            "type": [
                                "int",
                                {
                                    "type": "bytes",
                                    "logicalType": "decimal"
                                },
                                "string",
                                {
                                    "type": "record",
                                    "name": "amount",
                                    "fields": [
                                        {
                                            "name": "items_total",
                                            "type": {
                                                "type": "bytes",
                                                "logicalType": "decimal"
                                            }
                                        },
                                        {
                                            "name": "tax_amount",
                                            "type": {
                                                "type": "bytes",
                                                "logicalType": "decimal"
                                            }
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    ]
}
```

Le langage Data Shaping Query Language vous permet de référencer chaque type possible en écrivant l'index du type à la suite dans l'identifiant de l'élément à l'aide de la syntaxe suivante : identifier.@index. Dans cet exemple, int est la première valeur dans la liste des types possibles pour l'élément order\_amount, la référence est donc possible avec order\_amount.@0.

Cette syntaxe peut également être utilisée comme identifiant hiérarchique. Par exemple, vous pouvez référencer l'élément tax\_amount dans l'enregistrement, à l'aide de order\_amount.@3.tax\_amount.

Vous pouvez identifier le type utilisé pour chaque itération ou un élément, à l'aide de la fonction resolveChoice. Pour plus d'informations concernant cette fonction, consultez [Fonctions spéciales](https://help.qlik.com/talend/fr-FR/data-shaping-language-reference-guide/8.0/special-functions).

Dans cet exemple, vous pouvez utiliser la requête suivante pour obtenir le type de données utilisé pour l'élément order\_amount dans chaque élément du tableau orders :

```
FROM orders
SELECT {
    order_id,
    amount = resolveChoice(order_amount)
}
```

Cette requête retourne le résultat suivant :

```
[
    {
        "order_id": "abc-12345",
        "amount_type": 0
    },
    {
        "order_id": "def-67890",
        "amount_type": 2
    },
    {
        "order_id": "ghi-54321",
        "amount_type": 1
    },
    {
        "order_id": "jkl-09876",
        "amount_type": 3
    }
]
```

Vous pouvez ensuite écrire une requête pour harmoniser vos données et retourner un seul type de données pour l'élément order\_amount. Par exemple, vous pouvez utiliser la requête suivante pour :

* Attribuer un type à chaque index alternatif à l'aide d'une expression switch et de la fonction resolveChoice.
* Convertir les valeurs des chaînes de caractères et des entiers en valeurs décimales, à l'aide de la fonction toDecimal.
* Calculer le montant total de chaque enregistrement en ajoutant tax\_amount à items\_total.

```
FROM orders
LET $amount_type = 
    SWITCH (resolveChoice(order_amount)) { 
		CASE 0: 'INT' 
		CASE 1: 'DECIMAL' 
		CASE 2: 'STRING' 
		CASE 3: 'RECORD' 
	}
SELECT {
    order_id,
    amount = 
        IF ($amount_type = "STRING" OR $amount_type = "INT") 
            toDecimal(order_amount)
        ELSEIF ($amount_type = "RECORD")
            order_amount.@3.items_total + order_amount.@3.tax_amount
        ELSE order_amount
}
```

Avec cette requête, chaque itération de order\_amount est convertie en une valeur décimale, quel que soit le type d'entrée. Elle retourne le résultat suivant :

```
[
    {
        "order_id": "abc-12345",
        "amount": 250
    },
    {
        "order_id": "def-67890",
        "amount": 299.99
    },
    {
        "order_id": "ghi-54321",
        "amount": 435.95
    },
    {
        "order_id": "jkl-09876",
        "amount": 407.88
    }
]
```