SQL user-defined functions (SQL UDF) memungkinkan Anda mendefinisikan fungsi yang dapat digunakan kembali langsung dalam SQL tanpa menulis kode Java atau Python. Berbeda dengan UDF Java atau Python, SQL UDF tidak memerlukan kompilasi, unggah resource, maupun alur pendaftaran terpisah—cukup tulis isi fungsi sebagai ekspresi SQL dan panggil segera.
SQL UDF juga mendukung parameter bertipe fungsi, yang memungkinkan Anda meneruskan fungsi bawaan, UDF lain, atau fungsi anonim sebagai argumen—mirip dengan ekspresi Lambda.
Konsep utama
| Konsep | Deskripsi |
|---|---|
| SQL UDF permanen | Dibuat dengan CREATE SQL FUNCTION. Disimpan dalam sistem metadata MaxCompute, terlihat dalam daftar fungsi, dan dapat dipanggil dari skrip atau sesi mana pun. |
| Temporary SQL UDF | Dibuat dengan FUNCTION (tanpa awalan CREATE SQL). Hanya berlaku dalam skrip tempat fungsinya didefinisikan dan tidak dapat dipanggil di tempat lain. |
| Parameter bertipe fungsi | Parameter input yang menerima fungsi sebagai nilainya — baik fungsi bawaan, UDF lain, maupun fungsi anonim. |
| Mode skrip SQL | Mode eksekusi yang diperlukan saat mendefinisikan SQL UDF. Mendefinisikan UDF dalam mode pengeditan SQL biasa dapat menyebabkan error. |
Prasyarat
Sebelum memulai, pastikan Anda telah:
-
Memiliki lingkungan yang berjalan dalam mode skrip SQL. Untuk detailnya, lihat SQL dalam mode skrip.
-
Memastikan tipe data parameter input yang akan digunakan didukung oleh MaxCompute. Untuk daftar lengkapnya, lihat Edisi tipe data MaxCompute V2.0.
-
Memiliki izin tingkat fungsi yang diperlukan pada Akun Alibaba Cloud Anda. Untuk detailnya, lihat Izin MaxCompute.
Membuat SQL UDF permanen
SQL UDF permanen disimpan dalam sistem metadata MaxCompute. Setelah dibuat, fungsi tersebut muncul dalam daftar fungsi dan dapat dipanggil dari fase apa pun.
Sintaks
CREATE SQL FUNCTION <function_name>(@<parameter_in1> <datatype>[, @<parameter_in2> <datatype>...])
[RETURNS @<parameter_out> <datatype>]
AS [BEGIN]
<function_expression>
[END];
Parameter
| Parameter | Wajib | Deskripsi |
|---|---|---|
function_name |
Ya | Nama SQL UDF. Harus unik dalam proyek dan tidak boleh sama dengan nama fungsi bawaan apa pun. Setiap nama hanya dapat didaftarkan satu kali. Jalankan LIST FUNCTIONS untuk memeriksa konflik. |
parameter_in |
Ya | Parameter input. Masing-masing diawali dengan @. Parameter dapat bertipe fungsi — lihat Meneruskan fungsi sebagai parameter. |
datatype |
Ya | Tipe data setiap parameter input. Harus merupakan tipe data yang didukung MaxCompute. |
RETURNS @parameter_out |
Tidak | Variabel return. Jika dihilangkan, nilai function_name dikembalikan secara default. |
function_expression |
Ya | Ekspresi SQL yang mengimplementasikan logika fungsi. Dapat mereferensi operator bawaan, fungsi bawaan, atau UDF lain. |
BEGIN / END |
Tidak | Opsional. Digunakan untuk membungkus logika multi-pernyataan ketika isi fungsi berisi lebih dari satu pernyataan. |
Contoh
Fungsi sederhana — tambahkan 1 ke input BIGINT:
CREATE SQL FUNCTION my_add(@a BIGINT) AS @a + 1;
Fungsi multi-pernyataan menggunakan BEGIN / END:
CREATE SQL FUNCTION my_sum(@a BIGINT, @b BIGINT, @c BIGINT) RETURNS @my_sum BIGINT
AS BEGIN
@temp := @a + @b;
@my_sum := @temp + @c;
END;
Membuat SQL UDF temporary
SQL UDF temporary tidak disimpan di MaxCompute. Fungsi ini hanya berlaku dalam skrip SQL tempat didefinisikan dan tidak dapat dipanggil dalam sesi atau skrip lain.
Sintaks
FUNCTION <function_name>(@<parameter_in1> <datatype>[, @<parameter_in2> <datatype>...])
[RETURNS @<parameter_out> <datatype>]
AS [BEGIN]
<function_expression>
[END];
Parameter-parameternya identik dengan yang digunakan pada CREATE SQL FUNCTION. Hilangkan CREATE SQL untuk membuat UDF temporary.
Contoh
FUNCTION my_add(@a BIGINT) AS @a + 1;
Kueri SQL UDF
Hanya SQL UDF permanen yang dapat ditanyakan—SQL UDF temporary tidak disimpan di MaxCompute.
Untuk menjalankan DESC FUNCTION dari klien MaxCompute (odpscmd), upgrade klien ke versi 0.34.0 atau yang lebih baru. Untuk instruksi instalasi dan peningkatan, lihat Klien MaxCompute (odpscmd).
Sintaks
DESC FUNCTION <function_name>;
Contoh
DESC FUNCTION my_add;
Output:
Name my_add
Owner ALIYUN$s***_****@**.aliyunid.com
Created Time 2021-05-08 11:26:02
SQL Definition Text CREATE SQL FUNCTION MY_ADD(@a BIGINT) AS @a + 1
Memanggil SQL UDF
Panggil SQL UDF dengan cara yang sama seperti memanggil fungsi bawaan.
-
SQL UDF permanen dapat dipanggil dalam fase apa pun.
-
SQL UDF temporary hanya dapat dipanggil dalam skrip tempat fungsinya didefinisikan.
Tipe data argumen yang Anda berikan harus sesuai dengan tipe data yang didefinisikan dalam UDF.
Sintaks
SELECT <function_name>(<column_name>[, ...]) FROM <table_name>;
Contoh
-- Buat tabel dan masukkan data sampel.
CREATE TABLE src (c BIGINT, d STRING);
INSERT INTO TABLE src VALUES (1, '100.1'), (2, '100.2'), (3, '100.3');
-- Panggil my_add pada kolom c.
SELECT my_add(c) FROM src;
Output:
+------------+
| _c0 |
+------------+
| 2 |
| 3 |
| 4 |
+------------+
Menghapus SQL UDF
Sintaks
DROP FUNCTION <function_name>;
Contoh
DROP FUNCTION my_add;
Meneruskan fungsi sebagai parameter
SQL UDF mendukung parameter bertipe fungsi. Saat Anda mendeklarasikan parameter sebagai FUNCTION (<input_type>) RETURNS <output_type>, pemanggil dapat meneruskan fungsi apa pun yang kompatibel—fungsi bawaan, UDF lain (Java, Python, atau SQL), atau fungsi anonim.
Contoh
-- Definisikan SQL UDF.
FUNCTION add(@a BIGINT) AS @a + 1;
-- Definisikan UDF orde tinggi yang menerima fungsi sebagai argumen.
FUNCTION op(@a BIGINT, @fun FUNCTION (BIGINT) RETURNS BIGINT) AS @fun(@a);
-- Panggil op, meneruskan fungsi berbeda sebagai argumen kedua.
-- add adalah SQL UDF; abs adalah fungsi bawaan MaxCompute.
SELECT op(key, add), op(key, abs) FROM VALUES (1), (2) AS t(key);
Output:
+------------+------------+
| _c0 | _c1 |
+------------+------------+
| 2 | 1 |
| 3 | 2 |
+------------+------------+
_c0 adalah hasil dari add(key) (menambahkan 1). _c1 adalah hasil dari abs(key) (nilai absolut). Untuk detail fungsi ABS, lihat Fungsi matematika.
Untuk tindakan pencegahan penggunaan ekspresi Lambda di MaxCompute, lihat Fungsi Lambda.
Menggunakan fungsi anonim
Saat memanggil UDF dengan parameter bertipe fungsi, teruskan fungsi anonim inline daripada fungsi bernama. Kompilator melakukan inferensi tipe parameter fungsi anonim berdasarkan signature UDF.
Contoh
FUNCTION op(@a BIGINT, @fun FUNCTION (BIGINT) RETURNS BIGINT) AS @fun(@a);
-- Teruskan fungsi anonim sebagai argumen kedua.
SELECT op(key, FUNCTION (@a) AS @a + 1) FROM VALUES (1), (2) AS t(key);
FUNCTION (@a) AS @a + 1 adalah fungsi anonim tersebut. Tipe parameternya diinferensi dari signature op—tidak perlu deklarasi tipe eksplisit.
Contoh: menyederhanakan logika SQL yang berulang
Skenario: Konversi string tanggal dari format yyyy-mm-dd ke yyyymmdd. Tanggal inputnya adalah 2020-11-21, 2020-1-01, 2019-5-1, dan 19-12-1.
Menggunakan SQL UDF (disarankan)
Definisikan logika konversi sekali, lalu panggil fungsinya di mana saja diperlukan:
CREATE SQL FUNCTION y_m_d2yyyymmdd(@y_m_d STRING) RETURNS @yyyymmdd STRING
AS BEGIN
@yyyymmdd := CONCAT(
LPAD(SPLIT_PART(@y_m_d, '-', 1), 4, '0'),
LPAD(SPLIT_PART(@y_m_d, '-', 2), 2, '0'),
LPAD(SPLIT_PART(@y_m_d, '-', 3), 2, '0')
);
END;
SELECT y_m_d2yyyymmdd(d) FROM VALUES ('2020-11-21'), ('2020-1-01'), ('2019-5-1'), ('19-12-1') AS t(d);
Output:
+------------+
| _c0 |
+------------+
| 20201121 |
| 20200101 |
| 20190501 |
| 00191201 |
+------------+
Tanpa SQL UDF
Sertakan seluruh ekspresi secara inline di setiap lokasi pemanggilan—lebih sulit dipelihara dan rentan error jika logika perlu diubah:
SELECT CONCAT(
LPAD(SPLIT_PART(d, '-', 1), 4, '0'),
LPAD(SPLIT_PART(d, '-', 2), 2, '0'),
LPAD(SPLIT_PART(d, '-', 3), 2, '0')
) FROM VALUES ('2020-11-21'), ('2020-1-01'), ('2019-5-1'), ('19-12-1') AS t(d);
Batasan
| Batasan | Detail |
|---|---|
| Mode eksekusi | SQL UDF harus didefinisikan dalam mode skrip SQL. Mendefinisikan UDF dalam mode pengeditan SQL biasa dapat menyebabkan error. Lihat SQL dalam mode skrip. |
| Kompatibilitas tipe data | Tipe data parameter input harus merupakan tipe yang didukung MaxCompute. Tipe data argumen yang diberikan saat memanggil SQL UDF harus sesuai dengan tipe yang didefinisikan dalam UDF. Lihat Edisi tipe data MaxCompute V2.0. |
| Izin | Membuat, menanyakan, memanggil, atau menghapus SQL UDF memerlukan izin tingkat fungsi. Lihat Izin MaxCompute. |
| Keunikan nama fungsi | Nama fungsi harus unik dalam suatu proyek dan tidak boleh sama dengan nama fungsi bawaan. Setiap nama hanya dapat didaftarkan satu kali. |
| Cakupan UDF temporary | SQL UDF temporary hanya dapat dipanggil dalam skrip tempat didefinisikan. Fungsi ini tidak disimpan dan tidak dapat ditanyakan dalam daftar fungsi. |
| Versi klien query | Menanyakan SQL UDF dengan DESC FUNCTION dari klien odpscmd memerlukan versi klien 0.34.0 atau yang lebih baru. |