Tüm Ürünler
Search
Belge Merkezi

MaxCompute:Betik Modu SQL

Son Güncelleme:Oct 10, 2026

Betik modu, birden fazla SQL ifadesini tek bir birim olarak derleyip gönderir. Bu işlem, kuyruğa bir kez alınan ve tek bir işte çalışan tek bir yürütme planı oluşturur. Bu yaklaşım; birden fazla koordineli ifade gerektiren ETL veri işlem hatları, periyodik toplu işleme ve sorgu orkestrasyonu senaryoları için idealdir. Normal mod (atomik yürütme, varsayılan) ve adım adım yürütme modu (seri yürütme) desteği sunar.

  • Betik modu maliyet tahmini desteklemez. Gerçek ücretler faturalama ayrıntılarınıza göre belirlenir.

  • Tek bir betik en fazla 10.000 tabloya başvurabilir. Her başvuru ayrı ayrı sayılır; aynı tabloya yapılan tekrarlı başvurular ve görünüm tanımlarındaki tablolar da buna dahildir.

  • Birden fazla veri kaynağı için veri hazırlama işlemleri önemli ölçüde farklı zamanlarda tamamlanıyorsa (örneğin biri saat 01:00'de, diğeri saat 07:00'de), bunları tek bir Betik Modu SQL işinde birleştirmek için tablo değişkeni kullanmayın.

Kullanım Senaryoları

  • Karmaşık ifadeleri yeniden yazma: Derin iç içe geçmiş alt sorguları, okunabilir tablo değişkeni atamalarından oluşan bir diziye ayırın.

  • Çoklu ifadeli işlem hatları oluşturma: Mantıksal olarak ilişkili ifadeleri tek bir işte birleştirerek kuyruk ve zamanlama ek yükünü azaltın. Normal modda tüm ifadeler atomik olarak yürütülür. Adım adım yürütme modunda ifadeler seri halde çalışır; bu durum, yazdıktan sonra okuma senaryoları veya diğer platformlardan geçişler için uygundur. Daha fazla bilgi için bkz. Yürütme Modları.

Sözdizimi

  • İfade türleri: Betik modu SET ifadelerini, bazı DDL ifadelerini ve DML ifadelerini destekler. DESC ve SHOW gibi sonuç görüntüleyen ifadeler desteklenmez.

  • İfade sırası: Bir betik sabit bir SET → DDL → DML sırasını izlemelidir. Her bölüm sıfır veya daha fazla ifade içerebilir, ancak farklı bölümlerden gelen ifadeleri iç içe yerleştiremezsiniz.

-- 1. SET
SET odps.sql.type.system.odps2=true;
[SET odps.stage.reducer.num=xxx;]
[SET odps.sql.step.script.mode=true;] -- Enable step-by-step execution mode
[...]
-- 2. DDL
CREATE TABLE table1 xxx;
[CREATE TEMPORARY TABLE table2 xxx;] -- Create a temporary table
[...]
-- 3. DML&DQL
@var1 := SELECT [ALL | DISTINCT] select_expr, select_expr, ...
        FROM table3
        [WHERE where_condition];
@var2 := SELECT [ALL | DISTINCT] select_expr, select_expr, ...
        FROM table4
        [WHERE where_condition];
@var3 := SELECT [ALL | DISTINCT] var1.select_expr, var2.select_expr, ...
        FROM @var1 JOIN @var2 ON ...;
INSERT OVERWRITE|INTO TABLE [PARTITION (partcol1=val1, partcol2=val2 ...)]
        SELECT [ALL | DISTINCT] select_expr, select_expr, ...
        FROM @var3;    
[@var4 := SELECT [ALL | DISTINCT] var1.select_expr, var1.select_expr, ... FROM @var1 
        UNION ALL | UNION 
        SELECT [ALL | DISTINCT] var2.select_expr, var2.select_expr, ... FROM @var2;    
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
        AS 
        SELECT [ALL | DISTINCT] select_expr, select_expr, ...
        FROM @var4;]
[...]

Yürütme Modları

Betik modu iki yürütme modunu destekler.


Davranış


Normal mod (varsayılan)


Adım adım yürütme modu


Nasıl etkinleştirilir


Varsayılandır. Yapılandırma gerekmez.


SET bölümüne SET odps.sql.step.script.mode=true; ekleyin.


Derleme


Tüm DML ifadeleri tek bir yürütme planında derlenir.


Her DML ifadesi ayrı bir yürütme planında derlenir. Not: Binlerce satır veya çok sayıda işlem içeren çok karmaşık betikler, derleme belleği sınırlarını aşabilir.


Yürütme


Tüm ifadeler, tüm giriş verileri hazır olduktan sonra başlayan tek bir iş olarak atomik şekilde yürütülür. Herhangi bir ifade başarısız olursa tüm betik başarısız olur ve tüm işlemler geri alınır.


DML ifadeleri seri olarak yürütülür. Bir ifade başarısız olursa, önceden yürütülen ifadeler geri alınmaz ve betiği baştan tekrar çalıştırmanız gerekir. Büyük betikleri daha küçük parçalara ayırmanızı öneririz.


Yazdıktan sonra okuma


Desteklenmez. Bir betikte aynı tabloya yazıp ardından ondan okumaya çalışırsanız hata oluşur.


Desteklenir, ancak işlemsel veya bölümlenmiş tablolar için geçerli değildir.


Geçici tablo


Desteklenmez.


Desteklenir.

DDL Sözdizimi

Geçici tablo oluşturma

Geçici tablolar, aynı betik içinde yeniden kullanılmak üzere ara sonuçları önbelleğe alır. Yazdıktan sonra okuma düzenine dayandıkları için yalnızca adım adım yürütme modunda desteklenirler.

Sözdizimi

CREATE TEMPORARY TABLE <table_name> (
  <col_name> <data_type>, ...
)
[LIFECYCLE <days>]
[AS <select_statement>];

Parametreler


Parametre


Açıklama


table_name


Yalnızca geçerli betik içinde erişilebilir.


LIFECYCLE <days>


İsteğe bağlı. Tablo otomatik olarak silinmeden önce saklanacak gün sayısı. Varsayılan: 1.


AS <select_statement>


İsteğe bağlı. Oluşturulurken tabloyu bir SELECT ifadesinden gelen verilerle doldurur.

Sınırlamalar

  • Geçici tablolar adım adım yürütme modu gerektirir. Betiğinizin SET bölümüne SET odps.sql.step.script.mode=true; ekleyin.

  • Geçici tabloya yalnızca oluşturulduğu betik içinde erişilebilir.

  • Geçici tablolar bölümlenmiş tablolar veya işlemsel tablolar olamaz.

  • Geçici bir tabloyu açıkça silmek için DROP TABLE ifadesi betikteki son ifade olmalıdır.

  • Tek bir betikte 20'den fazla geçici tablo oluşturmaktan kaçının.

Standart tablo oluşturma

Betik modu standart tabloların oluşturulmasını destekler. Sözdizimi ayrıntıları için bkz. CREATE TABLE.

DML ve DQL Sözdizimi

İfade Sınırlamaları

  • Sonuç görüntüleyen ifadeler: Bir betik, bağımsız bir SELECT ifadesi gibi ekran çıktısı üreten yalnızca bir ifade içerebilir. Birden fazla ifade bulunması hataya neden olur. Betiklerde bu tür ifadeleri kullanmaktan kaçının.

  • CREATE TABLE AS: Bu ifadeyi betik başına yalnızca bir kez kullanabilirsiniz ve son yürütülebilir ifade olmalıdır. Önce tabloyu oluşturup ardından veri eklemenizi öneririz.

  • Karışık yazma modları: Aynı betik içinde aynı tablo için hem OVERWRITE hem de INTO kullanamazsınız. İşlemsel tablolar ve standart tablolar üzerindeki DML işlemleri karıştırılamaz.

  • Yazdıktan sonra okuma: Normal modda, aynı betik içinde bir tabloya yazıp ardından ondan okumak hataya neden olur. Bu sorunu çözmek için ya bir tablo değişkeni kullanın ya da adım adım yürütme moduna geçin. Adım adım yürütme modu yazdıktan sonra okuma işlemini destekler ancak işlemsel tablolar veya bölümlenmiş tablolar için geçerli değildir. Ayrıntılı örnek için bkz. Örnek 3: Normal modda yazdıktan sonra okuma.

Değişkenler

Sözdizimi

-- Declare a variable by using @. Supported types include TABLE and any MaxCompute data type.
@var1 <type>
-- Assign a value by using :=
@var1 := <select_statement>

Kullanım Notları

  • Tablo türündeki bir değişkeni belirli bir veri türüne sahip bir değişkene atayamazsınız. Örneğin, aşağıdaki sözdizimine izin verilmez:

    @a TABLE (name STRING);
    @a := SELECT 'tom';
    @b STRING;
    @b := SELECT * FROM @a;
  • Değişkenler sabit değerleri depolayabilir. SELECT * FROM @var kullanarak bir değişkenin değerini skaler değere dönüştürebilirsiniz. Aşağıdaki örnekte gösterildiği gibi bir sabit, tek satırlık bir tabloda da depolanabilir. Dönüşüm sözdizimi hakkında daha fazla bilgi için bkz. alt sorgu.

    @a := SELECT 10;                                         -- Assign the constant 10
    @b := SELECT key, value + (SELECT * FROM @a) FROM t2;   -- Use @a as a scalar
    SELECT * FROM @b;

IF İfadeleri

Koşullara dayalı olarak yürütme akışını kontrol etmek için IF ifadelerini kullanın.

Sözdizimi

-- Single branch
IF (condition) BEGIN
  statements
END
-- Multi-branch
IF (condition) BEGIN
  statements
END ELSE IF (condition2) BEGIN
  statements
END ELSE BEGIN
  statements
END

Kullanım Notları

  • Bir dal yalnızca tek bir ifade içeriyorsa, BEGIN ve END anahtar sözcükleri isteğe bağlıdır (Java'daki { } benzeri).

  • CREATE TABLE, ALTER TABLE ve TRUNCATE TABLE gibi DDL ifadeleri bir IF dalı içinde desteklenmez.

  • Koşul iki türü destekler:

    • Boolean ifadesi: Dal derleme zamanında belirlenir.

    • Boolean skaler alt sorgusu: Dal çalışma zamanında belirlenir. MaxCompute birden fazla iş gönderebilir.

Örnek 1: IF ifadesinde koşul BOOLEAN türünde bir ifadedir. Bu tür IF ELSE ifadesi, aşağıdaki örnekte gösterildiği gibi hangi dalın yürütüleceğini derleme zamanında belirleyebilir:

@date := '20190101';
@row TABLE(id STRING);
IF (CAST(@date AS BIGINT) % 2 == 0) BEGIN
  @row := SELECT id FROM src1;
END ELSE BEGIN
  @row := SELECT id FROM src2;
END
INSERT OVERWRITE TABLE dest SELECT * FROM @row;

Örnek 2: IF ifadesindeki koşul bir Boolean skaler alt sorgusudur. Bu tür IF ELSE ifadesi için yürütme dalı çalışma zamanında belirlenir; bu durum MaxCompute'in birden fazla iş göndermesini gerektirir:

@i BIGINT;
@t TABLE(id BIGINT, value BIGINT);
IF ((SELECT COUNT(*) FROM src WHERE a = '5') > 1) BEGIN
  @i := 1;
  @t := SELECT @i, @i*2;
END ELSE BEGIN
  @i := 2;
  @t := SELECT @i, @i*2;
END
SELECT id, value FROM @t;

Örnekler

Örnek 1: Temel Örnek

Aşağıdaki betik, üç kaynak tablodan gelen verileri birleştirir ve union işlemine tabi tutar, ardından sonuçları iki hedef tabloya ekler. Tüm ifadeler tek bir DAG'de derlenir ve atomik olarak yürütülür.

CREATE TABLE IF NOT EXISTS dest(key STRING, value BIGINT) PARTITIONED BY (d STRING);
CREATE TABLE IF NOT EXISTS dest2(key STRING, value BIGINT) PARTITIONED BY (d STRING);
@a := SELECT * FROM src  WHERE value > 0;
@b := SELECT * FROM src2 WHERE key IS NOT NULL;
@c := SELECT * FROM src3 WHERE value IS NOT NULL;
@d := SELECT a.key, b.value FROM @a LEFT OUTER JOIN @b ON a.key = b.key AND b.value > 0;
@e := SELECT a.key, c.value FROM @a INNER JOIN @c ON a.key = c.key;
@f := SELECT * FROM @d UNION SELECT * FROM @e UNION SELECT * FROM @a;
INSERT OVERWRITE TABLE dest  PARTITION (d='20171111') SELECT * FROM @f;
@g := SELECT e.key, c.value FROM @e JOIN @c ON e.key = c.key;
INSERT OVERWRITE TABLE dest2 PARTITION (d='20171111') SELECT * FROM @g;

Örnek 2: Adım adım modda yazdıktan sonra okuma

Aşağıdaki betik, aynı betik içinde yazdıktan sonra okuma işlemi gerçekleştirmek üzere adım adım yürütme modunu etkinleştirir.

SET odps.sql.step.script.mode=true;
DROP TABLE IF EXISTS foo_t1;
DROP TABLE IF EXISTS foo_t2;
CREATE TABLE foo_t1(a STRING) LIFECYCLE 1;
CREATE TABLE foo_t2(a STRING) LIFECYCLE 1;
@x := SELECT 'hello, world' AS a;
INSERT OVERWRITE TABLE foo_t1 SELECT * FROM @x;
INSERT INTO foo_t2 SELECT * FROM foo_t1 UNION ALL SELECT * FROM foo_t1;
SELECT * FROM foo_t2;

Örnek 3: Normal modda yazdıktan sonra okuma

Normal modda, aynı betik içinde bir tabloya yazıp ardından ondan okumak hataya neden olur. Bu örnek hatayı ve iki olası çözümü göstermektedir.

Veri hazırlığı

CREATE TABLE src(key BIGINT, value BIGINT) LIFECYCLE 1;
CREATE TABLE src2(key BIGINT, value BIGINT) LIFECYCLE 1;
INSERT INTO src VALUES(1, 2), (3, 3);

Hata örneği (normal modda yazdıktan sonra okuma)

INSERT OVERWRITE TABLE src2 SELECT * FROM src WHERE key > 0;
@a := SELECT * FROM src2;   -- Error: src2 is written to and then read from in the same script.
SELECT * FROM @a;

Çözüm 1: Adım adım yürütme modunu etkinleştirin

SET odps.sql.step.script.mode=true;
INSERT OVERWRITE TABLE src2 SELECT * FROM src WHERE key > 0;
@a := SELECT * FROM src2;
SELECT * FROM @a;

Çözüm 2: SQL'i bir tablo değişkeni kullanacak şekilde yeniden yazın

@a := SELECT * FROM src WHERE key > 0;
INSERT OVERWRITE TABLE src2 SELECT * FROM @a;
SELECT * FROM @a;

Örnek 4: Geçici tablo oluşturma ve silme

Aşağıdaki betik, bir JOIN işleminin ara sonuçlarını önbelleğe almak için geçici bir tablo oluşturur, bu tablodan iki kez okur ve ardından tabloyu siler.

-- Enable step-by-step execution mode (required for temporary tables).
SET odps.sql.step.script.mode=true;
DROP TABLE IF EXISTS foo_t1;
CREATE TABLE foo_t1(a BIGINT, b BIGINT);
-- Create a temporary table by using a JOIN.
CREATE TEMPORARY TABLE t AS
SELECT t1.a AS a, t2.d AS b FROM
  (SELECT 1 a, 2 b) t1
JOIN
  (SELECT 1 c, 10 d) t2
ON t1.a = t2.c;
INSERT INTO foo_t1 SELECT * FROM t UNION ALL SELECT * FROM t;
SELECT * FROM foo_t1;
-- Drop the temporary table (must be the last statement in the script).
DROP TABLE t;

Betik Gönderme

Betik modu MaxCompute Studio, MaxCompute istemcisi (odpscmd), DataWorks ve Java ile Python SDK'larında desteklenir.

MaxCompute istemcisi (odpscmd)

odpscmd v0.27 veya sonraki bir sürümü kullanın. MaxCompute istemcisini yükledikten sonra, -s bayrağını kullanarak bir betik gönderin:

myscript.sql gibi bir betik dosyası oluşturun. Ardından, odpscmd'yi çalıştırmak için komut satırı arayüzünüzden aşağıdaki komutu çalıştırın. Komut satırından MaxCompute istemcisini çalıştırma hakkında daha fazla bilgi için bkz. MaxCompute istemcisini çalıştırma.

..\bin>odpscmd -s myscript.sql
Not

odpscmd etkileşimli kabuğunda betik modu ve tablo değişkenleri desteklenmez. -s bayrağı, -f ve -e benzeri şekilde odpscmd için bir komut satırı seçeneğidir. Etkileşimli ortamda bir komut değildir.

DataWorks

DataWorks'te betikleri yazmak ve çalıştırmak için bir ODPS Script düğümü kullanın.

Sol üst köşede + Oluştur > Düğüm Oluştur seçeneğine tıklayın. MaxCompute kategorisi altında ODPS Script öğesini seçin.

Betik yazıldıktan sonra, araç çubuğundaki Run simgesine tıklayarak betiği yürütün. Çıktı günlüğü, yürütme planını ve sonuçları kontrol etmek için bir Logview URL'si içerir.

SDK'lar

SQL betiklerini doğrudan Java SDK veya Python SDK ile çalıştırın. Daha fazla bilgi için Java SDK ve Python SDK belgelerine bakın.

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.aliyun.odps.Instance;
import com.aliyun.odps.Odps;
import com.aliyun.odps.OdpsException;
import com.aliyun.odps.account.Account;
import com.aliyun.odps.account.AliyunAccount;
import com.aliyun.odps.data.Record;
import com.aliyun.odps.task.SQLTask;
public class SdkTest {
  public static void main(String[] args) throws OdpsException {
    // Your Alibaba Cloud AccessKey pair grants full access to your account and carries high risks.
    // We strongly recommend that you create and use a RAM user for API calls and daily operations.
    // To create a RAM user, log on to the RAM console.
    // This example shows how to use environment variables to store your credentials.
    // For security, never hard-code your AccessKey pair into your code.
    Account account = new AliyunAccount(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
    Odps odps = new Odps(account);
    odps.setDefaultProject("your project_name");
    odps.setEndpoint("your end_point");
    String sqlScript = "@a := SELECT * FROM jdbc_test;\n"
                       + "SELECT * FROM @a;";
    // Required: Enable script mode.
    Map<String, String> hints = new HashMap<>();
    hints.put("odps.sql.submit.mode", "script");
    Instance instance = SQLTask.run(odps, "your project_name", sqlScript, hints, null);
    instance.waitForSuccess();
    List<Record> recordList = SQLTask.getResult(instance);
    for (Record record : recordList) {
      System.out.println(record.get(0));
      System.out.println(record.get(1));
    }
  }
}
import os
from odps import ODPS
# Your Alibaba Cloud AccessKey pair grants full access to your account and carries high risks.
# We strongly recommend that you create and use a RAM user for API calls and daily operations.
# To create a RAM user, log on to the RAM console.
# This example shows how to use environment variables to store your credentials.
# For security, never hard-code your AccessKey pair into your code.
o = ODPS(
    os.environ["ALIBABA_CLOUD_ACCESS_KEY_ID"],
    os.environ["ALIBABA_CLOUD_ACCESS_KEY_SECRET"],
    "your project_name",
    "your end_point"
)
sql_script = """
@a := SELECT * FROM jdbc_test;
SELECT * FROM @a;
"""
# Required: Enable script mode.
hints = {"odps.sql.submit.mode", "script"}
instance = o.execute_sql(sql_script, hints=hints)
with instance.open_reader() as reader:
    for rec in reader:
        print(rec[0], rec[1])

MaxCompute Studio

MaxCompute Studio'da bir betik çalıştırmadan önce aşağıdaki ön koşulları tamamlayın:

  1. IntelliJ IDEA'yı yükleme

  2. Proje bağlantısı ekleme

  3. MaxCompute Script modülü oluşturma

Betiği çalıştırdıktan sonra, betik birden fazla ifade içerse bile MaxCompute Studio yürütme planını tek bir DAG olarak görüntüler.