Todos os produtos
Search
Central de documentação

MaxCompute:UDFs com código incorporado

Última atualização: Jun 26, 2026

As UDFs com código incorporado permitem definir lógica Java ou Python diretamente em um script SQL, eliminando o fluxo separado de compilação, upload e registro das UDFs padrão. Como as instruções SQL e o código da função residem no mesmo arquivo, a lógica torna-se imediatamente visível e mais fácil de manter.

Envie todos os exemplos desta página em modo script.

Quando usar UDFs com código incorporado

Use UDFs com código incorporado quando:

  • A função for usada apenas no script atual e não precisar de reutilização em vários jobs SQL.

  • Desejar manter a implementação e a consulta juntas em um único arquivo para melhorar a legibilidade.

  • Estiver criando protótipos ou iterando rapidamente e quiser pular a etapa de empacotamento JAR.

Prefira uma UDF padrão quando:

  • Vários scripts SQL compartilharem a mesma lógica de função.

  • O código Java depender de recursos incompatíveis com o compilador Janino (consulte Limitações).

  • A base de código for muito grande para incorporação inline.

Como funciona

Ao compilar um script com um bloco de código incorporado, o MaxCompute usa o compilador Janino para identificar e extrair esse código, compilá-lo, gerar recursos dinamicamente e criar uma função temporária. Essa função temporária não é armazenada como entrada persistente no sistema de metadados do MaxCompute.

Referência rápida de sintaxe

Parâmetro

Valores

Descrição

lang

JAVA, PYTHON

Linguagem do código incorporado

filename

Qualquer string

Nome de arquivo virtual. Obrigatório para UDFs Python (usado na cláusula AS). Também utilizado em UDTFs Java (em @Resolve). Opcional para UDFs Java.

Sintaxe do bloco de código incorporado:

#CODE ('lang'='JAVA')
  <your Java or Python code>
#END CODE;

Posicionamento do bloco de código:

Posicionamento

Escopo

Após USING em CREATE TEMPORARY FUNCTION

Aplica-se apenas a essa instrução CREATE TEMPORARY FUNCTION

No final do script

Aplica-se a todo o script

Limitações

O compilador Janino compila o código Java incorporado e suporta apenas um subconjunto da sintaxe padrão do JDK. Os seguintes recursos não estão disponíveis:

Limitação

Solução alternativa

Expressões lambda não são suportadas.

Múltiplos tipos de exceção em um único bloco catch não são suportados. `catch(Exception1

Exception2 e)` não é permitido.

Inferência de argumentos genéricos não é suportada. Map map = new HashMap<>() não é permitido.

Especifique o tipo explicitamente: Map<String, String> map = new HashMap<String, String>().

Expressões para inferência de argumentos de tipo são ignoradas.

Use expressões de cast: (String) myMap.get(key).

Assertions estão sempre ativadas, independentemente da definição da opção JVM -ea.

Versões do Java posteriores ao Java 8 não são suportadas.

Referenciar código incorporado em um tipo definido pelo usuário (UDT)

Coloque o bloco de código incorporado no final do script. Ele se aplicará a todo o script.

SELECT
  s,
  com.mypackage.Foo.extractNumber(s)
FROM VALUES ('abc123def'), ('apple') AS t(s);

#CODE ('lang'='JAVA')
package com.mypackage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Foo {
  final static Pattern compile = Pattern.compile(".*?([0-9]+).*");
  public static String extractNumber(String input) {
    final Matcher m = compile.matcher(input);
    if (m.find()) {
      return m.group(1);
    }
    return null;
  }
}
#END CODE;

Chame a classe incorporada usando seu nome totalmente qualificado (com.mypackage.Foo.extractNumber) diretamente na consulta SQL.

Definir e chamar uma UDF Java

Posicione o bloco de código incorporado imediatamente após USING para restringir seu escopo à instrução CREATE TEMPORARY FUNCTION ou no final do script.

CREATE TEMPORARY FUNCTION foo AS 'com.mypackage.Reverse' USING
#CODE ('lang'='JAVA')
package com.mypackage;
import com.aliyun.odps.udf.UDF;
public class Reverse extends UDF {
  public String evaluate(String input) {
    if (input == null) return null;
    StringBuilder ret = new StringBuilder();
    for (int i = input.toCharArray().length - 1; i >= 0; i--) {
      ret.append(input.toCharArray()[i]);
    }
    return ret.toString();
  }
}
#END CODE;

SELECT foo('abdc');

CREATE TEMPORARY FUNCTION cria uma função temporária válida apenas para a execução atual. Ela não é armazenada no sistema de metadados do MaxCompute. Para criar uma função permanente, consulte CREATE SQL FUNCTION.

Definir e chamar uma função de valor de tabela definida pelo usuário (UDTF) Java

CREATE TEMPORARY FUNCTION foo AS 'com.mypackage.Reverse' USING
#CODE ('lang'='JAVA', 'filename'='embedded.jar')
package com.mypackage;

import com.aliyun.odps.udf.UDTF;
import com.aliyun.odps.udf.UDFException;
import com.aliyun.odps.udf.annotation.Resolve;

@Resolve({"string->string,string"})
public class Reverse extends UDTF {
  @Override
  public void process(Object[] objects) throws UDFException {
    String str = (String) objects[0];
    String[] split = str.split(",");
    forward(split[0], split[1]);
  }
}

#END CODE;

SELECT foo('ab,dc') AS (a,b);
O compilador Janino não reconhece "string->string,string" como tipo string[] . Coloque os parâmetros de @Resolve entre chaves {} — por exemplo, @Resolve({"string->string,string"}) . Essa solução alternativa é necessária apenas para UDTFs com código incorporado; UDTFs padrão não exigem as chaves.

Definir e chamar uma UDF Python

CREATE TEMPORARY FUNCTION foo AS 'embedded.UDFTest' USING
#CODE ('lang'='PYTHON', 'filename'='embedded')
from odps.udf import annotate
@annotate("bigint->bigint")
class UDFTest(object):
  def evaluate(self, a):
    return a * a
#END CODE;

SELECT foo(4);

Dois detalhes são específicos para UDFs Python:

  • Nome de arquivo virtual: O nome da classe na cláusula AS deve incluir o nome do arquivo source Python. Use 'filename'='embedded' para especificar esse nome de arquivo virtual.

  • Indentação: O código Python dentro do bloco incorporado deve seguir as regras padrão de indentação do Python.

Para guias de desenvolvimento específicos por versão do Python, consulte Desenvolver uma UDF em Python 2 e Desenvolver uma UDF em Python 3.