

 Amazon Redshift tidak akan lagi mendukung pembuatan Python UDFs baru mulai Patch 198. Python yang ada UDFs akan terus berfungsi hingga 30 Juni 2026. Untuk informasi lebih lanjut, lihat [posting blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Struktur PL/PGSQL
<a name="c_PLpgSQL-structure"></a>

PL/PGSQL adalah bahasa prosedural dengan banyak konstruksi yang sama dengan bahasa prosedural lainnya. 

**Topics**
+ [Blokir](#r_PLpgSQL-block)
+ [Deklarasi variabel](#r_PLpgSQL-variable-declaration)
+ [Deklarasi alias](#r_PLpgSQL-alias-declaration)
+ [Variabel bawaan](#r_PLpgSQL-builtin-variables)
+ [Jenis rekaman](#r_PLpgSQL-record-type)

## Blokir
<a name="r_PLpgSQL-block"></a>

PL/pgSQL is a block-structured language. The complete body of a procedure is defined in a block, which contains variable declarations and PL/pgSQLpernyataan. Pernyataan juga bisa berupa blok bersarang, atau subblok. 

Akhiri deklarasi dan pernyataan dengan titik koma. Ikuti kata kunci END di blok atau subblok dengan titik koma. Jangan gunakan titik koma setelah kata kunci DECLARE dan BEGIN. 

Anda dapat menulis semua kata kunci dan pengidentifikasi dalam huruf besar dan kecil campuran. Pengidentifikasi secara implisit dikonversi ke huruf kecil kecuali diapit dalam tanda kutip ganda.

Tanda hubung ganda (--) memulai komentar yang meluas ke akhir baris. A /\$1 memulai komentar blok yang meluas ke kejadian berikutnya dari \$1/. Anda tidak dapat memblokir komentar sarang. Namun, Anda dapat melampirkan komentar tanda hubung ganda dalam komentar blok, dan tanda hubung ganda dapat menyembunyikan pembatas komentar blok /\$1 dan \$1/.

Pernyataan apa pun di bagian pernyataan blok dapat berupa subblok. Anda dapat menggunakan subblok untuk pengelompokan logis atau untuk melokalisasi variabel ke sekelompok kecil pernyataan.

```
[ <<label>> ]
[ DECLARE
  declarations ]
BEGIN
  statements
END [ label ];
```

Variabel yang dideklarasikan di bagian deklarasi sebelum blok diinisialisasi ke nilai defaultnya setiap kali blok dimasukkan. Dengan kata lain, mereka tidak diinisialisasi hanya sekali per panggilan fungsi.

Bagian berikut menunjukkan satu contoh.

```
CREATE PROCEDURE update_value() AS $$
DECLARE
  value integer := 20;
BEGIN
  RAISE NOTICE 'Value here is %', value;  -- Value here is 20
  value := 50;
  --
  -- Create a subblock
  --
  DECLARE
    value integer := 80;
  BEGIN
    RAISE NOTICE 'Value here is %', value;  -- Value here is 80
  END;

  RAISE NOTICE 'Value here is %', value;  -- Value here is 50
END;
$$ LANGUAGE plpgsql;
```

Gunakan label untuk mengidentifikasi blok yang akan digunakan dalam pernyataan EXIT atau untuk memenuhi syarat nama variabel yang dideklarasikan di blok.

Jangan bingung penggunaan hanya untuk pengelompokan. BEGIN/END for grouping statements in PL/pgSQL with the database commands for transaction control. The BEGIN and END in PL/pgSQL Mereka tidak memulai atau mengakhiri transaksi.

## Deklarasi variabel
<a name="r_PLpgSQL-variable-declaration"></a>

Deklarasikan semua variabel dalam blok, kecuali variabel loop, di bagian DECLARE blok. Variabel dapat menggunakan tipe data Amazon Redshift yang valid. Untuk tipe data yang didukung, lihat[Jenis Data](c_Supported_data_types.md). 

Variabel PL/PGSQL dapat berupa jenis data yang didukung Amazon Redshift, plus dan. `RECORD` `refcursor` Untuk informasi selengkapnya tentang `RECORD`, lihat [Jenis rekaman](#r_PLpgSQL-record-type). Untuk informasi selengkapnya tentang `refcursor`, lihat [Cursors](c_PLpgSQL-statements.md#r_PLpgSQL-cursors). 

```
DECLARE
name [ CONSTANT ] type [ NOT NULL ] [ { DEFAULT | := } expression ];
```

Berikut, Anda dapat menemukan contoh deklarasi variabel.

```
customerID integer;
numberofitems numeric(6);
link varchar;
onerow RECORD;
```

Variabel loop dari loop FOR iterasi pada rentang bilangan bulat secara otomatis dinyatakan sebagai variabel integer. 

Klausa DEFAULT, jika diberikan, menentukan nilai awal yang ditetapkan untuk variabel ketika blok dimasukkan. Jika klausa DEFAULT tidak diberikan, maka variabel diinisialisasi ke nilai SQL NULL. Opsi CONSTANT mencegah variabel ditetapkan, sehingga nilainya tetap konstan selama durasi blok. Jika NOT NULL ditentukan, penugasan nilai null menghasilkan kesalahan runtime. Semua variabel yang dinyatakan sebagai NOT NULL harus memiliki nilai default non-null yang ditentukan.

Nilai default dievaluasi setiap kali blok dimasukkan. Misalnya, menetapkan `now()` ke variabel tipe `timestamp` menyebabkan variabel memiliki waktu pemanggilan fungsi saat ini, bukan waktu ketika fungsi dikompilasi sebelumnya.

```
quantity INTEGER DEFAULT 32;
url VARCHAR := 'http://mysite.com';
user_id CONSTANT INTEGER := 10;
```

Tipe `refcursor` data adalah tipe data variabel kursor dalam prosedur tersimpan. `refcursor`Nilai dapat dikembalikan dari dalam prosedur yang disimpan. Untuk informasi selengkapnya, lihat [Mengembalikan set hasil dari prosedur yang disimpan](stored-procedure-result-set.md).

## Deklarasi alias
<a name="r_PLpgSQL-alias-declaration"></a>

Jika tanda tangan prosedur tersimpan menghilangkan nama argumen, Anda dapat mendeklarasikan alias untuk argumen tersebut.

```
name ALIAS FOR $n;
```

## Variabel bawaan
<a name="r_PLpgSQL-builtin-variables"></a>

Variabel bawaan berikut didukung:
+ MENEMUKAN
+ SQLSTATE
+ SQLERRM
+ DAPATKAN DIAGNOSTIK integer\$1var: = ROW\$1COUNT;

FOUND adalah variabel khusus dari jenis Boolean. FOUND memulai false dalam setiap panggilan prosedur. FOUND diatur oleh jenis pernyataan berikut:
+ PILIH KE

  Set FOUND ke true jika mengembalikan baris, false jika tidak ada baris dikembalikan.
+ UPDATE, INSERT, dan DELETE

  Set FOUND ke true jika setidaknya satu baris terpengaruh, false jika tidak ada baris yang terpengaruh.
+ AMBIL

  Set FOUND ke true jika mengembalikan baris, false jika tidak ada baris dikembalikan.
+ UNTUK pernyataan

  Set FOUND ke true jika pernyataan FOR iterasi satu kali atau lebih, dan sebaliknya false. Ini berlaku untuk ketiga varian pernyataan FOR: integer FOR loop, record-set FOR loop, dan dynamic record-set FOR loop. 

  FOUND diatur ketika FOR loop keluar. Di dalam runtime loop, FOUND tidak dimodifikasi oleh pernyataan FOR. Namun, itu dapat diubah dengan menjalankan pernyataan lain di dalam badan loop.

Bagian berikut menunjukkan satu contoh.

```
CREATE TABLE employee(empname varchar);
CREATE OR REPLACE PROCEDURE show_found()
AS  $$
DECLARE
  myrec record;
BEGIN
  SELECT INTO myrec * FROM employee WHERE empname = 'John';
  IF NOT FOUND THEN
    RAISE EXCEPTION 'employee John not found';
  END IF;
END;
$$ LANGUAGE plpgsql;
```

Dalam handler pengecualian, variabel khusus SQLSTATE berisi kode kesalahan yang sesuai dengan pengecualian yang dimunculkan. Variabel khusus SQLERRM berisi pesan kesalahan yang terkait dengan pengecualian. Variabel ini tidak terdefinisi di luar penangan pengecualian dan menampilkan kesalahan jika digunakan.

Bagian berikut menunjukkan satu contoh.

```
CREATE OR REPLACE PROCEDURE sqlstate_sqlerrm() AS
$$
BEGIN
  UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith';
  EXECUTE 'select invalid';
  EXCEPTION WHEN OTHERS THEN
  RAISE INFO 'error message SQLERRM %', SQLERRM;
  RAISE INFO 'error message SQLSTATE %', SQLSTATE;
END;
$$ LANGUAGE plpgsql;
```

ROW\$1COUNT digunakan dengan perintah GET DIAGNOSTICS. Ini menunjukkan jumlah baris yang diproses oleh perintah SQL terakhir yang dikirim ke mesin SQL.

Bagian berikut menunjukkan satu contoh.

```
CREATE OR REPLACE PROCEDURE sp_row_count() AS
$$
DECLARE
  integer_var int;
BEGIN
  INSERT INTO tbl_row_count VALUES(1);
  GET DIAGNOSTICS integer_var := ROW_COUNT;
  RAISE INFO 'rows inserted = %', integer_var;
END;
$$ LANGUAGE plpgsql;
```

## Jenis rekaman
<a name="r_PLpgSQL-record-type"></a>

Tipe RECORD bukan tipe data yang benar, hanya placeholder. Variabel tipe rekaman mengasumsikan struktur baris sebenarnya dari baris yang ditetapkan selama perintah SELECT atau FOR. Substruktur variabel record dapat berubah setiap kali diberi nilai. Sampai variabel record pertama kali ditugaskan, ia tidak memiliki substruktur. Setiap upaya untuk mengakses bidang di dalamnya akan menimbulkan kesalahan runtime.

```
name RECORD;
```

Bagian berikut menunjukkan satu contoh.

```
CREATE TABLE tbl_record(a int, b int);
INSERT INTO tbl_record VALUES(1, 2);
CREATE OR REPLACE PROCEDURE record_example()
LANGUAGE plpgsql
AS $$
DECLARE
  rec RECORD;
BEGIN
  FOR rec IN SELECT a FROM tbl_record
  LOOP
    RAISE INFO 'a = %', rec.a;
  END LOOP;
END;
$$;
```