PL/SQL Subprograms

8.16.2. Input Data Partitioning

Deklarasi table function dapat menentukan data partitioning untuk tepat satu parameter REF CURSOR. Sintaks untuk melakukan hal ini adalah sebagai berikut:

CREATE FUNCTION f(p ref cursor type) RETURN rec_tab_type PIPELINED
PARALLEL_ENABLE(PARTITION p BY [{HASH | RANGE} (column list) | ANY ]) IS
BEGIN ... END;

Frasa PARTITIONED…BY dalam klausa PARALLEL_ENABLE menentukan input cursor yang mana yang digunakan untuk mempartisi dan kolom-kolom mana saja yang digunakan untuk partitioning.

Ketika nama kolom eksplisit ditentukan dalam daftar kolom, metode partition dapat berupa RANGE atau HASH. Baris-baris input akan di hash- atau range-partitioned pada kolom-kolom yang telah ditentukan.

Keyword ANY mengindikasikan bahwa kelakuan function adalah independen dari partitioning dari input data. Ketika keyword ini digunakan, runtime system secara random mempartisi data diantara slaves. Keyword ini sesuai untuk digunakan bersama functions yang menerima satu baris data, memanipulasi kolom-kolomnya, dan menghasilkan baris(-baris) output berdasarkan pada kolom-kolom dari baris-baris data ini saja.

Sebagai contoh, pivot-like function StockPivot yang ditunjukkan berikut ini menerima satu baris data sebagai input dari type:

(Ticker varchar(4), OpenPrice number, ClosePrice number)

dan menghasilkan baris-baris data dari type tersebut:

(Ticker varchar(4), PriceType varchar(1), Price number).

Jadi baris data (”ORCL”, 41, 42) menghasilkan dua baris data (”ORCL”, “O”, 41) dan (”ORCL”, “C”, 42).

CREATE FUNCTION StockPivot(p refcur_pkg.refcur_t) RETURN rec_tab_type PIPELINED
PARALLEL_ENABLE(PARTITION p BY ANY) IS
ret_rec rec_type;
BEGIN
  FOR rec IN p LOOP
    ret_rec.Ticker := rec.Ticker;
    ret_rec.PriceType := "O";
    ret_rec.Price := rec.OpenPrice;
    PIPE ROW(ret_rec);
    ret_rec.Ticker := rec.Ticker; -- Redundant; not required
    ret_rec.PriceType := "C";
    ret_rec.Price := rec.ClosePrice;
    push ret_rec;
  END LOOP;
  RETURN;
END;

Function f dapat digunakan untuk menghasilkan table yang lain dari table Stocks dalam cara sebagai berikut:

INSERT INTO AlternateStockTable
SELECT * FROM
TABLE(StockPivot(CURSOR(SELECT * FROM StockTable)));

Jika StockTable di scan dalam paralel dan di partisi pada OpenPrice, maka function StockPivot yang dikombinasikan dengan data-flow operator melakukan scan dari StockTable dan dengan demikian melihat partitioning yang sama.

Jika, dengan kata lain, StockTable tidak dipartisi, dan scan terhadapnya tidak dieksekusi dalam paralel, penambahan terhadap AlternateStockTable juga berjalan secara sekuensial. Berikut ini sebuah contoh yang sedikit lebih kompleks:

INSERT INTO AlternateStockTable
SELECT *
FROM TABLE(f(CURSOR(SELECT * FROM Stocks))),
TABLE(g(CURSOR( ... )))
WHERE join_condition;

dimana g didefinisikan menjadi:

CREATE FUNCTION g(p refcur_pkg.refcur_t) RETURN ... PIPELINED
PARALLEL_ENABLE (PARTITION p BY ANY)
BEGIN ... END;

Jika function g berjalan dalam paralel dan terpartisi berdasarkan ANY, maka penambahan data paralel dapat termasuk di dalam operator data-flow yang sama seperti g.

Kapanpun keyword ANY ditentukan, data dipartisi secara random diantara slaves. Hal ini secara efektif berarti bahwa function tersebut dieksekusi dalam slave set yang sama yang melakukan scan yang terkait dengan input parameter.

Tidak diperlukan distritusi dan partisi ulang data disini. Jika cursor p itu sendiri tidak terparalel, data yang masuk akan secara random dipartisi pada kolom-kolom di dalam daftar kolom. Antrian round-robin table digunakan untuk partitioning ini.

8.16.3. Eksekusi Paralel dari Leaf-level Table Functions

Untuk menggunakan eksekusi paralel dengan sebuah function yang menghasilkan banyak baris data, namun tidak perlu menerima banyak baris data sebagai input dan sehingga tidak memerlukan sebuah REF CURSOR. Dengan cara seperti itu, function akan memiliki beberapa cara agar partition dapat bekerja.

Sebagai contoh, misalkan kita menginginkan sebuah function untuk membaca sebuah kumpulan dari file-file eksternal secara paralel dan mengembalikan record-record yang terkandung di dalamnya. Untuk menyediakan pekerjaan bagi sebuah REF CURSOR, pertama kita menciptakan sebuah table dan mempopulasikannya dengan nama-nama file. Sebuah REF CURSOR di atas table ini kemudian dapat dilewatkan sebagai sebuah parameter ke table function (readfiles). Kode berikut ini menunjukkan bagaimana hal ini dapat dilakukan:

CREATE TABLE filetab(filename VARCHAR(20));
INSERT INTO filetab VALUES('file0');
INSERT INTO filetab VALUES('file1');
...
INSERT INTO filetab VALUES('fileN');SELECT * FROM
TABLE(readfiles(CURSOR(SELECT filename FROM filetab)));
CREATE FUNCTION readfiles(p pkg.rc_t) RETURN coll_type
PARALLEL_ENABLE(PARTITION p BY ANY) IS
ret_rec rec_type;
BEGIN
  FOR rec IN p LOOP
    done := FALSE;
    WHILE (done = FALSE) LOOP
      done := readfilerecord(rec.filename, ret_rec);
      PIPE ROW(ret_rec);
    END LOOP;
  END LOOP;
  RETURN;
END;

 

Pages: 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

 

Buku ini membahas berbagai macam tip dan trik yang sangat berguna bagi Anda pembaca pengguna database Oracle. Pemula, mahasiswa, programmer, maupun database administrator yang mengharapkan solusi cepat dalam menangani permasalahan-permasalahan dalam penggunaan database Oracle dapat membaca buku ini. Anda tidak harus membaca buku ini secara urut karena buku ini di susun berdasarkan topik permasalahan, dan Anda dapat membaca topik-topik yang sesuai dengan permasalahan yang Anda hadapi.
Dapat di beli di toko buku Gramedia, Gunung Agung, Uranus, Karisma dsb. Harga Rp. 24.800,- (157 halaman)

 

Related Articles

 

Comments

[…] PL/SQL Subprograms | Hastinapura […]

[…] Silahkan melanjutkan membaca pembahasan PL/SQL Subprograms […]

[…] Klausa AUTHID menentukan apakah seluruh subprogram-subprogram ter-package dijalankan dengan privileges dari definer (default) atau invoker-nya, dan apakah referensi tak terkualifikasi dari mereka terhadap schema objects ditetapkan di dalam schema dari definer atau invoker tersebut. Untuk informasi lebih, kita dapat membaca kembali pembahasan PL/SQL Subprograms. […]

[…] Dynamic SQLPL/SQL Object TypesPL/SQL PackagesPL/SQL SubprogramsInteraksi PL/SQL dengan […]

Leave a comment

(required)

(required)


*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word