Tous les produits
Search
Centre de documentation

MaxCompute:SELECT TRANSFORM

Dernière mise à jour :Aug 20, 2026

L'instruction SELECT TRANSFORM permet de démarrer un processus enfant spécifié et d'utiliser l'entrée standard pour saisir des données dans le format requis. Vous pouvez ensuite analyser la sortie standard du processus enfant afin d'obtenir les données de sortie. L'instruction SELECT TRANSFORM vous permet d'exécuter des scripts écrits dans d'autres langages de programmation sans avoir à écrire de fonctions définies par l'utilisateur renvoyant une table (UDTF).

Description

Les performances de SELECT TRANSFORM et des UDTF varient selon les scénarios. Les résultats des tests comparatifs montrent que SELECT TRANSFORM offre de meilleures performances que les UDTF lors de l'interrogation de petits volumes de données. En revanche, les UDTF surpassent SELECT TRANSFORM pour les grands volumes de données. SELECT TRANSFORM est simple à développer et convient mieux aux requêtes ponctuelles.

SELECT TRANSFORM est compatible avec divers langages de programmation. Cette instruction vous permet d'écrire des scripts directement dans les commandes pour implémenter des fonctionnalités simples. Des langages tels qu'AWK, Python, Perl et Shell prennent en charge cette opération. Ainsi, vous n'avez pas besoin d'effectuer des opérations supplémentaires, telles que l'écriture de fichiers de script ou le téléchargement de ressources. Cela simplifie le processus de développement. Pour implémenter des fonctionnalités complexes, vous pouvez télécharger des fichiers de script. Pour plus d'informations, consultez les rubriques Exemple d'appel de scripts Python et Exemple d'appel de scripts Java.

Le tableau suivant présente les résultats de la comparaison entre les UDTF et SELECT TRANSFORM selon différentes dimensions.

Catégorie

select transform

UDTF

Type de données

Un processus enfant utilise l'entrée et la sortie standards pour transmettre les données. Toutes les données sont traitées sous forme de chaînes. Si vous utilisez SELECT TRANSFORM, une conversion de type de données est requise.

Les résultats de sortie et les paramètres d'entrée des UDTF prennent en charge plusieurs types de données.

Transmission des données

La transmission des données repose sur le pipeline du système d'exploitation. Toutefois, la taille du cache du pipeline est limitée à 4 Ko et ne peut pas être modifiée. Si le pipeline est vide ou entièrement occupé, SELECT TRANSFORM ne peut pas s'exécuter.

Lors de la transmission des données, SELECT TRANSFORM appelle les systèmes sous-jacents pour lire et écrire les données. Cette instruction offre de meilleures performances de transmission des données que les programmes Java.

Aucune limite n'est imposée au cache du pipeline.

Transmission des paramètres constants

La transmission des paramètres constants est obligatoire.

La transmission des paramètres constants est facultative.

Processus

SELECT TRANSFORM prend en charge les processus parents et enfants. Si l'utilisation des ressources de calcul est élevée et le débit de données faible, SELECT TRANSFORM peut exploiter la fonctionnalité multicœur des serveurs.

Un seul processus est utilisé.

Performances

SELECT TRANSFORM prend en charge le code natif d'outils tels qu'AWK. Cela permet à SELECT TRANSFORM d'offrir de meilleures performances que les programmes Java.

Les performances sont faibles.

Limites

PHP et Ruby ne sont pas déployés sur les clusters de calcul MaxCompute. Par conséquent, vous ne pouvez pas appeler de scripts PHP ou Ruby dans MaxCompute.

Syntaxe

select transform(<arg1>, <arg2> ...) 
[(row format delimited (fields terminated by <field_delimiter> (escaped by <character_escape>)) (null defined as <null_value>))]
using '<unix_command_line>' 
(resources '<res_name>' (',' '<res_name>')*)
[(as <col1>, <col2> ...)]
(row format delimited (fields terminated by <field_delimiter> (escaped by <character_escape>)) (null defined as <null_value>))
  • Mot-clé SELECT TRANSFORM : obligatoire. Vous pouvez remplacer ce mot-clé par map ou reduce, qui ont la même sémantique. Pour clarifier la syntaxe, nous vous recommandons d'utiliser SELECT TRANSFORM.

  • arg1,arg2... : obligatoire. Ces paramètres spécifient les données d'entrée. Leurs formats sont identiques à ceux des instructions SELECT. Si vous utilisez les formats par défaut, les résultats des expressions pour chaque paramètre sont implicitement convertis en valeurs de type STRING. Ensuite, les paramètres sont combinés avec \t et transmis au processus enfant spécifié.

  • Clause ROW FORMAT : facultative. Cette clause vous permet de personnaliser le format des données d'entrée et de sortie.

    La syntaxe utilise deux clauses ROW FORMAT. La première définit le format des données d'entrée, tandis que la seconde spécifie celui des données de sortie. Par défaut, le séparateur de colonne est \t, le séparateur de ligne est \n et la valeur nulle est représentée par \N.

    Remarque
    • Les paramètres field_delimiter et character_escape n'acceptent qu'un seul caractère. Si vous indiquez une chaîne, seul le premier caractère est pris en compte.

    • MaxCompute prend en charge les syntaxes définies par Apache Hive, telles que inputRecordReader, outputRecordReader et SerDe. Pour les utiliser, activez l'édition des types de données compatible avec Hive en ajoutant set odps.sql.hive.compatible=true; avant vos instructions SQL. Consultez la documentation Hive pour plus de détails sur les syntaxes supportées par Apache Hive.

    • L'utilisation de syntaxes propres à Apache Hive, comme inputRecordReader ou outputRecordReader, peut ralentir l'exécution des instructions SQL.

  • Clause USING : obligatoire. Elle indique la commande permettant de lancer un processus enfant.

    • Dans la plupart des instructions SQL MaxCompute, la clause USING désigne des ressources. Dans une instruction SELECT TRANSFORM, elle spécifie la commande de démarrage du processus enfant, afin d'assurer la compatibilité avec la syntaxe d'Apache Hive.

    • La syntaxe de la clause USING ressemble à celle d'un script shell, mais elle crée directement un processus enfant à partir de la commande indiquée plutôt que d'exécuter un script. Certaines fonctionnalités shell, telles que la redirection des entrées/sorties, les pipelines ou les boucles, ne sont donc pas disponibles. Vous pouvez toutefois invoquer un script shell comme commande de lancement si nécessaire.

  • Clause RESOURCES : facultative. Elle définit les ressources accessibles au processus enfant. Deux méthodes sont possibles :

    • Indiquez les ressources directement dans la clause RESOURCES, par exemple using 'sh foo.sh bar.txt' resources 'foo.sh','bar.txt'.

    • Utilisez le paramètre set odps.sql.session.resources. Ajoutez par exemple set odps.sql.session.resources=foo.sh,bar.txt; avant vos instructions SQL.

      Une fois cette configuration globale appliquée, toutes les instructions SELECT TRANSFORM peuvent accéder aux ressources indiquées. Séparez les différents fichiers par des virgules (,).

  • Clause AS : facultative. Elle précise les colonnes de sortie et leurs types de données, par exemple as(col1 bigint, col2 boolean).

    • Si aucun type n'est indiqué, STRING est appliqué par défaut. Ainsi, AS(col1, col2) signifie que les colonnes de sortie sont de type STRING.

    • Les données de sortie proviennent de l'analyse de la sortie standard du processus enfant. Si le type spécifié diffère de STRING, MaxCompute appelle implicitement la fonction CAST pour effectuer la conversion, ce qui peut provoquer une exception lors de l'exécution.

    • Il est impossible de définir les types uniquement pour certaines colonnes, comme dans as(col1, col2:bigint).

    • Si vous omettez la clause AS, le champ précédant le premier \t dans la sortie standard devient la clé, et le reste constitue la valeur. Cela équivaut à AS(key, value).

Exemple d'appel de commandes shell

Exécutez une commande shell pour générer 50 lignes de données, allant de 1 à 50. La sortie correspond au champ data. Utilisez la sortie de la commande shell comme entrée pour SELECT TRANSFORM. Exemple d'instruction :

select transform(script) using 'sh' as (data) 
from (
        select  'for i in `seq 1 50`; do echo $i; done' as script
      ) t
;
-- The preceding statement is equivalent to the following statement: 
select transform('for i in `seq 1 50`; do echo $i; done') using 'sh' as (data);

Le résultat suivant est renvoyé :

+------------+
| data       |
+------------+
| 1          |
| 2          |
| 3          |
| 4          |
| 5          |
| 6          |
| 7          |
| 8          |
| 9          |
| 10         |
| 11         |
| 12         |
| 13         |
| 14         |
| 15         |
| 16         |
| 17         |
| 18         |
| 19         |
| 20         |
| 21         |
| 22         |
| 23         |
| 24         |
| 25         |
| 26         |
| 27         |
| 28         |
| 29         |
| 30         |
| 31         |
| 32         |
| 33         |
| 34         |
| 35         |
| 36         |
| 37         |
| 38         |
| 39         |
| 40         |
| 41         |
| 42         |
| 43         |
| 44         |
| 45         |
| 46         |
| 47         |
| 48         |
| 49         |
| 50         |
+------------+

Exemple d'appel de commandes Python

Utilisez une commande Python pour générer 50 lignes de données, allant de 1 à 50. La sortie correspond au champ data. Utilisez la sortie de la commande Python comme entrée pour SELECT TRANSFORM. Exemple d'instruction :

select transform(script) using 'python' as (data) 
from (
        select  'for i in xrange(1, 51):  print(i);' as script
      ) t
;
-- The preceding statement is equivalent to the following statement: 
select transform('for i in xrange(1, 51):  print(i);') using 'python' as (data);

Le résultat suivant est renvoyé :

+------------+
| data       |
+------------+
| 1          |
| 2          |
| 3          |
| 4          |
| 5          |
| 6          |
| 7          |
| 8          |
| 9          |
| 10         |
| 11         |
| 12         |
| 13         |
| 14         |
| 15         |
| 16         |
| 17         |
| 18         |
| 19         |
| 20         |
| 21         |
| 22         |
| 23         |
| 24         |
| 25         |
| 26         |
| 27         |
| 28         |
| 29         |
| 30         |
| 31         |
| 32         |
| 33         |
| 34         |
| 35         |
| 36         |
| 37         |
| 38         |
| 39         |
| 40         |
| 41         |
| 42         |
| 43         |
| 44         |
| 45         |
| 46         |
| 47         |
| 48         |
| 49         |
| 50         |
+------------+

Exemple d'appel de commandes AWK

Créez une table de test. Exécutez une commande AWK pour fournir la deuxième colonne de la table de test en tant que sortie. Les données de sortie correspondent au champ data. Utilisez la sortie de la commande AWK comme entrée pour SELECT TRANSFORM. Exemple d'instruction :

-- Create a test table. 
create table testdata(c1 bigint,c2 bigint);
-- Insert test data into the test table.  
insert into table testdata values (1,4),(2,5),(3,6); 
-- Execute the SELECT TRANSFORM statement.  
select transform(*) using "awk '//{print $2}'" as (data) from testdata;

Le résultat suivant est renvoyé :

+------------+
| data       |
+------------+
| 4          |
| 5          |
| 6          |
+------------+

Exemple d'appel de commandes Perl

Créez une table de test. Exécutez une commande Perl pour fournir les données de la table de test en tant que sortie. Les données de sortie correspondent au champ data. Utilisez la sortie de la commande Perl comme entrée pour SELECT TRANSFORM. Exemple d'instruction :

-- Create a test table. 
create table testdata(c1 bigint,c2 bigint);
-- Insert test data into the test table.  
insert into table testdata values (1,4),(2,5),(3,6); 
-- Execute the SELECT TRANSFORM statement.  
select transform(testdata.c1, testdata.c2) using "perl -e 'while($input = <STDIN>){print $input;}'" from testdata;

Le résultat suivant est renvoyé :

+------------+------------+
| key        | value      |
+------------+------------+
| 1          | 4          |
| 2          | 5          |
| 3          | 6          |
+------------+------------+

Exemple d'appel de scripts Python

  1. Créez le fichier myplus.py. Exemple de code :

    #!/usr/bin/env python
    import sys
    line = sys.stdin.readline()
    while line:
        token = line.split('\t')
        if (token[0] == '\\N') or (token[1] == '\\N'):
            print('\\N')
        else:
            print(str(token[0]) +'\t' + str(token[1]))
        line = sys.stdin.readline()
  2. Ajoutez le fichier de script Python en tant que ressource dans MaxCompute.

    add py ./myplus.py -f;
    Remarque

    Vous pouvez également utiliser la console DataWorks pour ajouter le fichier Python en tant que ressource. Pour plus d'informations, consultez la rubrique Créer et utiliser des ressources MaxCompute.

  3. Exécutez l'instruction SELECT TRANSFORM pour appeler ce fichier.

    -- Create a test table. 
    create table testdata(c1 bigint,c2 bigint);
    -- Insert test data into the test table.  
    insert into table testdata values (1,4),(2,5),(3,6); 
    -- Execute the SELECT TRANSFORM statement.  
    select 
    transform (testdata.c1, testdata.c2) 
    using 'python myplus.py' resources 'myplus.py' 
    as (result1,result2) 
    from testdata;
    -- The preceding statements are equivalent to the following statements: 
    set odps.sql.session.resources=myplus.py;
    select transform (testdata.c1, testdata.c2) 
    using 'python myplus.py' 
    as (result1,result2) 
    from testdata;

    Le résultat suivant est renvoyé :

    +------------+------------+
    | result1    | result2    |
    +------------+------------+
    | 1          | 4          |
    |            | NULL       |
    | 2          | 5          |
    |            | NULL       |
    | 3          | 6          |
    |            | NULL       |
    +------------+------------+

Exemple d'appel de scripts Java

  1. Rédigez un script Java et exportez-le sous forme de fichier Sum.jar. Exemple de code Java :

    package com.aliyun.odps.test;
    import java.util.Scanner;
    public class Sum {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            while (sc.hasNext()) {
                String s = sc.nextLine();
                String[] tokens = s.split("\t");
                if (tokens.length < 2) {
                    throw new RuntimeException("illegal input");
                }
                if (tokens[0].equals("\\N") || tokens[1].equals("\\N")) {
                    System.out.println("\\N");
                }
                System.out.println(Long.parseLong(tokens[0]) + Long.parseLong(tokens[1]));
            }
        }
    }
  2. Ajoutez le fichier en tant que ressource dans MaxCompute.

    add jar ./Sum.jar -f;
  3. Exécutez l'instruction SELECT TRANSFORM pour appeler ce fichier.

    -- Create a test table. 
    create table testdata(c1 bigint,c2 bigint); 
    -- Insert test data into the test table. 
    insert into table testdata values (1,4),(2,5),(3,6); 
    -- Execute the SELECT TRANSFORM statement. 
    select transform(testdata.c1, testdata.c2) using 'java -cp Sum.jar com.aliyun.odps.test.Sum' resources 'Sum.jar' as cnt from testdata;
    -- The preceding statements are equivalent to the following statements: 
    set odps.sql.session.resources=Sum.jar; 
    select transform(testdata.c1, testdata.c2) using 'java -cp Sum.jar com.aliyun.odps.test.Sum' as cnt from testdata;

    Le résultat suivant est renvoyé :

    +-----+
    | cnt |
    +-----+
    | 5   |
    | 7   |
    | 9   |
    +-----+
Remarque

Java et Python disposent d'un framework UDTF prêt à l'emploi. Toutefois, l'instruction SELECT TRANSFORM simplifie l'écriture des scripts. SELECT TRANSFORM ne nécessite aucune dépendance supplémentaire, n'impose aucun format spécifique et permet même d'utiliser directement des scripts hors ligne. Le répertoire de sauvegarde des scripts Java hors ligne peut être obtenu via la variable d'environnement JAVA_HOME. Le répertoire de sauvegarde des scripts Python hors ligne peut être obtenu via la variable d'environnement PYTHON_HOME.

Exemple d'appel de scripts en série

Vous pouvez exécuter les instructions SELECT TRANSFORM en série. Pour ce faire, utilisez les clauses DISTRIBUTE BY et SORT BY afin de prétraiter les données d'entrée. Exemple d'instruction :

select transform(key, value) using '<cmd2>' from 
(
    select transform(*) using '<cmd1>' from 
    (
        select * from testdata distribute by c2 sort by c1 
    ) t distribute by key sort by value 
) t2;

Les éléments cmd1 et cmd2 correspondent aux commandes utilisées pour démarrer les processus enfants.

Vous pouvez également utiliser les mots-clés map et reduce pour exécuter les instructions SELECT TRANSFORM en série.

@a := select * from data distribute by col2 sort by col1;
@b := map * using 'cmd1' distribute by col1 sort by col2 from @a;
reduce * using 'cmd2' from @b;