Lewati ke konten utama

20 Pertanyaan dan Jawaban Wawancara PL/SQL Teratas pada 2026

Persiapkan wawancara PL/SQL dengan topik kunci seperti fungsi, trigger, SQL dinamis, penanganan error, praktik terbaik, dan pertanyaan berbasis skenario dunia nyata.
Diperbarui 16 Apr 2026  · 10 mnt baca

PL/SQL, yang merupakan ekstensi bahasa prosedural Oracle untuk SQL, wajib Anda kuasai jika akan bekerja dengan database Oracle. Hal ini berlaku untuk peran-peran utama seperti administrator database, pengembang, dan analis data, yang semuanya perlu menangani logika bisnis kompleks di dalam database.

Menurut saya, pewawancara menilai kandidat berdasarkan tiga aspek utama:

  • Pemahaman Konseptual: Prinsip inti, tipe data, struktur kontrol, dan penanganan pengecualian.
  • Kemampuan Koding Praktis: Menulis stored procedure, function, trigger, dan package yang efisien.
  • Pertimbangan Kinerja: Mengoptimalkan kode PL/SQL untuk meningkatkan waktu eksekusi, meminimalkan konsumsi sumber daya, dan menghindari kesalahan seperti terlalu sering berpindah konteks antara SQL dan PL/SQL.

Untuk membantu, saya menyediakan panduan pertanyaan wawancara PL/SQL. Saya akan mulai dari konsep dasar dan berlanjut ke topik yang lebih maju seperti pemrosesan bulk, SQL dinamis, dan penalaan kinerja.

Jika Anda ingin memahami konsep dasar database Oracle, saya sarankan mengikuti kursus Introduction to Oracle SQL kami, yang merupakan sumber daya sangat penting untuk mempelajari cara berinteraksi dengan database Oracle dan bagaimana database menggunakan PL/SQL untuk memproses kueri.

Pertanyaan Wawancara PL/SQL untuk Pemula

Pada tahap awal wawancara, pewawancara dapat menanyakan pertanyaan mendasar untuk menilai pengetahuan Anda tentang konsep database dan PL/SQL. Coba pelajari pertanyaan dan jawaban ini untuk mempersiapkan fase awal wawancara.

1. Apa itu PL/SQL?

PL/SQL adalah ekstensi prosedural Oracle untuk SQL. Berbeda dengan SQL, yang bersifat deklaratif dan berfokus pada pengambilan serta manipulasi data, PL/SQL memungkinkan pengembang menerapkan logika prosedural, sehingga menjadi alat yang kuat untuk menulis aturan bisnis kompleks di dalam database. PL/SQL mendukung variabel, loop, kondisi, penanganan pengecualian, dan pemrograman modular melalui procedure, function, dan package.

2. Apa struktur dasar dari sebuah blok PL/SQL?

Blok PL/SQL adalah unit eksekusi fundamental dalam PL/SQL, dan terdiri dari empat bagian utama:

  • DECLARE (Opsional): Digunakan untuk mendefinisikan variabel, konstanta, cursor, dan tipe buatan pengguna.

  • BEGIN: Bagian eksekusi tempat kueri SQL dan pernyataan prosedural ditulis.

  • EXCEPTION (Opsional): Menangani error dan pengecualian saat runtime untuk memastikan pemulihan error yang baik.

  • END;: Menandai akhir blok.

3. Apa tipe data PL/SQL yang esensial?

PL/SQL mendukung berbagai tipe data, yang dikategorikan sebagai berikut:

  • Tipe Skalar: Tipe bernilai tunggal seperti NUMBER, VARCHAR2, DATE, BOOLEAN.

  • Tipe Komposit: Koleksi seperti RECORD (struktur kustom) dan TABLE/VARRAY (array).

  • Tipe Referensi: Pointer ke objek database, seperti REF CURSOR untuk pemrosesan kueri dinamis.

4. Apa struktur kontrol dasar dalam PL/SQL?

PL/SQL menyertakan beberapa struktur kontrol yang membantu mengelola alur program:

  • Loop: Termasuk LOOP, FOR LOOP, dan WHILE LOOP, memungkinkan eksekusi pernyataan berulang.

  • Pernyataan Kondisional: Termasuk IF dan CASE, yang mengeksekusi blok kode berbeda berdasarkan kondisi. Fungsi DECODE() adalah contoh kondisional lain yang layak dipelajari. 

Pertanyaan Wawancara PL/SQL Tingkat Menengah

Setelah membahas pertanyaan dasar, sekarang mari beralih ke beberapa pertanyaan wawancara struktur data tingkat menengah. Setelah menguji pengetahuan dasar Anda, pewawancara akan menguji kemahiran teknis Anda dalam mengimplementasikan dan menggunakan konsep PL/SQL.

5. Apa perbedaan antara stored procedure dan function?

Stored procedure dan function sama-sama blok kode PL/SQL yang dapat digunakan kembali, tetapi memiliki tujuan yang cukup berbeda.

Stored procedure digunakan untuk melakukan operasi yang tidak mengembalikan nilai, seperti menyisipkan, memperbarui, atau menghapus data. Prosedur digunakan untuk tugas yang memodifikasi data atau melakukan operasi kompleks tanpa mengembalikan hasil.

Sebagai contoh, prosedur di bawah ini memperbarui salary karyawan dengan employee_id tertentu dengan menambahkan p_increment yang ditentukan sehingga gaji diperbarui secara dinamis berdasarkan parameter masukan,

CREATE PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER) AS  
BEGIN  
    -- Update the salary of the employee with the given ID  
    UPDATE employees  
    SET salary = salary + p_increment  
    WHERE employee_id = p_emp_id;  
END;

Sementara itu, function mengembalikan nilai setelah melakukan operasi. Function cocok untuk perhitungan atau pengambilan data yang perlu mengembalikan hasil.

Function berikut menyederhanakan pengambilan gaji karyawan, sehingga dapat digunakan kembali dalam kueri SQL atau prosedur lainnya.

CREATE FUNCTION get_employee_salary(p_emp_id NUMBER) RETURN NUMBER AS  
    v_salary NUMBER;  
BEGIN  
    -- Retrieve the salary for the given employee ID  
    SELECT salary INTO v_salary  
    FROM employees  
    WHERE employee_id = p_emp_id;  
    
    -- Return the retrieved salary  
    RETURN v_salary;  
END;

6. Apa itu package PL/SQL?

Package PL/SQL adalah kumpulan procedure, function, dan variabel terkait yang mengenkapsulasi kode untuk organisasi dan reusabilitas yang lebih baik. Package terdiri dari dua bagian:

  • Spesifikasi Package: Mendeklarasikan elemen publik (procedure, function, variabel).
  • Badan Package: Berisi detail implementasi procedure dan function yang dideklarasikan dalam spesifikasi.

Sebagai contoh, kueri di bawah ini membuat package employee_pkg yang mendefinisikan procedure untuk menaikkan gaji karyawan dan function untuk mengambil total jumlah karyawan, dengan implementasinya disediakan pada badan package.

-- Create a package named 'employee_pkg'
CREATE PACKAGE employee_pkg AS  

    -- Procedure to increase an employee's salary by a percentage  
    PROCEDURE raise_salary(p_emp_id NUMBER, p_percent NUMBER);  

    -- Function to return the total number of employees  
    FUNCTION get_total_employees RETURN NUMBER;  

END employee_pkg;

7. Apa itu trigger PL/SQL?

Trigger adalah blok PL/SQL yang dieksekusi otomatis sebagai respons terhadap peristiwa tertentu di database, seperti penyisipan, pembaruan, atau penghapusan. Trigger digunakan untuk menegakkan aturan bisnis. Trigger juga umum digunakan untuk melakukan audit. Trigger dikategorikan menjadi:

  • Trigger Tingkat Baris: Dieksekusi sekali untuk setiap baris yang terpengaruh.
  • Trigger Tingkat Pernyataan: Dieksekusi sekali per pernyataan SQL, terlepas dari jumlah baris yang terpengaruh.

Kueri di bawah ini membuat trigger AFTER UPDATE trg_salary_audit pada tabel employees yang mencatat perubahan gaji ke tabel salary_audit, dengan menangkap ID karyawan, gaji lama dan baru, serta cap waktu pembaruan.

-- Create or replace a trigger 'trg_salary_audit'
CREATE OR REPLACE TRIGGER trg_salary_audit  
AFTER UPDATE OF salary ON employees  -- Fires after salary updates in 'employees' table
FOR EACH ROW  -- Executes for each updated row
BEGIN  
    -- Inserts old and new salary details into 'salary_audit' table
    INSERT INTO salary_audit (employee_id, old_salary, new_salary, change_date)  
    VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);  
END;

Pelajari tutorial kami tentang SQL Triggers agar Anda siap jika topik trigger dibahas dalam wawancara. 

8. Apa metode penanganan pengecualian (exception handling) di PL/SQL?

PL/SQL menyediakan mekanisme penanganan error demi stabilitas dan mencegah crash. Jenis pengecualian meliputi:

  • Pengecualian Bawaan: Pengecualian built-in seperti NO_DATA_FOUND, TOO_MANY_ROWS, dan ZERO_DIVIDE.

  • Pengecualian Buatan Pengguna: Pengecualian kustom dideklarasikan menggunakan EXCEPTION dan dipicu dengan RAISE.

Sebagai contoh, blok PL/SQL berikut mengambil gaji karyawan dengan ID 100, memicu pengecualian kustom jika gaji di bawah 1000, dan menangani kemungkinan error, termasuk data karyawan yang tidak ditemukan dan pengecualian tak terduga.

DECLARE  
    v_salary NUMBER;  -- Variable to store the employee's salary  
    e_low_salary EXCEPTION;  -- Custom exception for low salary  

BEGIN  
    -- Retrieve salary of employee with ID 100  
    SELECT salary INTO v_salary FROM employees WHERE employee_id = 100;  

    -- Raise exception if salary is below 1000  
    IF v_salary < 1000 THEN  
        RAISE e_low_salary;  
    END IF;  

EXCEPTION  
    WHEN NO_DATA_FOUND THEN  -- Handle case where employee ID is not found  
        DBMS_OUTPUT.PUT_LINE('Employee not found.');  
    WHEN e_low_salary THEN  -- Handle custom low salary exception  
        DBMS_OUTPUT.PUT_LINE('Salary is below the allowed threshold.');  
    WHEN OTHERS THEN  -- Handle any other unexpected errors  
        DBMS_OUTPUT.PUT_LINE('An unexpected error occurred: ' || SQLERRM);  

END;

Praktik terbaik untuk penanganan pengecualian meliputi:

  • Selalu antisipasi potensi pengecualian.
  • Gunakan pesan error yang bermakna.
  • Catat pengecualian untuk keperluan audit.
  • Jaga agar kode penanganan pengecualian tetap ringkas dan fokus pada pemulihan.

9. Bagaimana Anda memverifikasi apakah pernyataan UPDATE dieksekusi atau tidak?

Atribut SQL %NOTFOUND dapat digunakan untuk menentukan apakah pernyataan UPDATE berhasil mengubah catatan atau tidak. Jika pernyataan SQL terakhir tidak memengaruhi baris mana pun, variabel ini mengembalikan TRUE.

Sebagai contoh, kueri di bawah ini memperbarui gaji karyawan di departemen 10 dengan menaikkannya 10%, lalu memeriksa apakah ada baris yang terpengaruh oleh pernyataan UPDATE menggunakan atribut %NOTFOUND. Jika tidak ada baris yang diperbarui, akan menampilkan pesan "No rows were updated." Jika ada baris yang diperbarui, akan menampilkan jumlah baris yang terpengaruh menggunakan atribut SQL%ROWCOUNT.

DECLARE
    -- Declare a variable to store the number of rows updated
    rows_updated INTEGER;
BEGIN
    -- Perform an UPDATE statement on the 'employees' table
    UPDATE employees
    SET salary = salary * 1.1
    WHERE department_id = 10;

    -- Check if any rows were updated by using %NOTFOUND
    IF SQL%NOTFOUND THEN
        -- If no rows were updated, print a message
        DBMS_OUTPUT.PUT_LINE('No rows were updated.');
    ELSE
        -- If rows were updated, print how many rows were affected
        rows_updated := SQL%ROWCOUNT;  -- Store the number of rows updated
        DBMS_OUTPUT.PUT_LINE(rows_updated || ' rows were updated.');
    END IF;
END;
/

Pertanyaan Wawancara PL/SQL Tingkat Lanjut

Sekarang mari telusuri beberapa pertanyaan tingkat lanjut jika Anda melamar peran senior yang membutuhkan lebih banyak pengalaman.

10. Apa metode untuk mengoptimalkan kinerja di PL/SQL?

Meminimalkan perpindahan konteks antara SQL dan PL/SQL sangat penting untuk mengoptimalkan kinerja. Setiap perpindahan menimbulkan overhead, yang dapat memperlambat waktu eksekusi, terutama dalam situasi yang melibatkan transisi sering antara keduanya.

11. Bagaimana Anda menggunakan operasi bulk untuk meminimalkan perpindahan konteks?

PL/SQL menyediakan teknik pemrosesan bulk untuk mengoptimalkan interaksi SQL-ke-PL/SQL dengan mengambil atau memodifikasi banyak baris sekaligus.

Sebagai contoh, blok PL/SQL di bawah ini mengambil semua karyawan dari departemen 10 menggunakan BULK COLLECT ke dalam sebuah koleksi dan mengiterasinya untuk mencetak nama setiap karyawan, meningkatkan kinerja dengan meminimalkan perpindahan konteks antara SQL dan PL/SQL.

DECLARE  
    -- Define a table-type collection based on the 'employees' table structure  
    TYPE emp_table IS TABLE OF employees%ROWTYPE;  
    v_emps emp_table;  -- Declare a variable of this type  

BEGIN  
    -- Bulk fetch employees from department 10 into the collection  
    SELECT * BULK COLLECT INTO v_emps FROM employees WHERE department_id = 10;  

    -- Loop through the collection and print employee names  
    FOR i IN 1..v_emps.COUNT LOOP  
        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_emps(i).employee_name);  
    END LOOP;  

END;

Selain itu, blok PL/SQL ini menggunakan FORALL untuk pembaruan bulk, menaikkan gaji sebesar 10% untuk karyawan dengan ID 101, 102, dan 103.

DECLARE  
    -- Define a table-type collection for employee IDs  
    TYPE t_emp_ids IS TABLE OF employees.employee_id%TYPE;  
    -- Initialize collection with specific employee IDs  
    v_emp_ids t_emp_ids := t_emp_ids(101, 102, 103);  

BEGIN  
    -- Bulk update salaries by 10% for specified employee IDs  
    FORALL i IN 1..v_emp_ids.COUNT  
        UPDATE employees SET salary = salary * 1.10 WHERE employee_id = v_emp_ids(i);  

END;

12. Apa itu SQL dinamis dan Ref Cursor?

SQL dinamis memungkinkan eksekusi pernyataan SQL secara dinamis saat runtime, yang berguna saat menangani nama tabel, kolom, atau struktur kueri yang variatif.

Blok PL/SQL berikut menggunakan SQL dinamis untuk menghitung jumlah baris dalam tabel employees dan mencetak hasilnya. Saya menyukai pendekatan ini karena memberikan fleksibilitas.

DECLARE  
    v_table_name VARCHAR2(50) := 'employees';  -- Store table name  
    v_count NUMBER;  -- Variable to hold row count  

BEGIN  
    -- Dynamically count rows in the specified table  
    EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || v_table_name INTO v_count;  

    -- Print the total count  
    DBMS_OUTPUT.PUT_LINE('Total Employees: ' || v_count);  

END;  

Ref Cursor adalah cursor dinamis yang dapat dibuka, diambil (fetch), dan ditutup saat runtime, memungkinkan pengiriman hasil kueri antar unit program.

Blok PL/SQL di bawah ini menggunakan REF CURSOR untuk mengambil dan mencetak nama karyawan dari departemen 20. Cursor dibuka secara dinamis, diiterasi menggunakan loop, dan ditutup setelah pemrosesan.

DECLARE  
    -- Define a REF CURSOR type  
    TYPE emp_ref_cursor IS REF CURSOR;  
    v_cursor emp_ref_cursor;  -- Declare a cursor variable  
    v_name employees.employee_name%TYPE;  -- Variable to store employee name  

BEGIN  
    -- Open the cursor for employees in department 20  
    OPEN v_cursor FOR SELECT employee_name FROM employees WHERE department_id = 20;  

    -- Fetch and print employee names in a loop  
    LOOP  
        FETCH v_cursor INTO v_name;  
        EXIT WHEN v_cursor%NOTFOUND;  
        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_name);  
    END LOOP;  

    -- Close the cursor  
    CLOSE v_cursor;  

END;

13. Bagaimana Anda menangani error mutating table?

Error mutating table terjadi ketika sebuah trigger mencoba memodifikasi tabel yang memicu trigger tersebut. Compound trigger memungkinkan pemecahan eksekusi trigger ke beberapa fase seperti BEFORE, AFTER, dan FOR EACH ROW untuk mencegah masalah modifikasi langsung.

Compound trigger di bawah ini mencatat perubahan gaji pada tabel salary_audit secara efisien dengan mengumpulkan data sebelum setiap pembaruan baris dan melakukan penyisipan bulk setelah pernyataan, mengurangi perpindahan konteks dan meningkatkan kinerja.

CREATE OR REPLACE TRIGGER trg_salary_audit  
FOR UPDATE OF salary ON employees  -- Trigger fires on salary updates  
COMPOUND TRIGGER  

    -- Declare an associative array to store audit records  
    TYPE t_salary_audit IS TABLE OF salary_audit%ROWTYPE INDEX BY PLS_INTEGER;  
    v_audit_data t_salary_audit;  
    v_idx PLS_INTEGER := 0;  

    -- Before updating each row, store old and new salary details  
    BEFORE EACH ROW IS  
    BEGIN  
        v_idx := v_idx + 1;  
        v_audit_data(v_idx).employee_id := :OLD.employee_id;  
        v_audit_data(v_idx).old_salary := :OLD.salary;  
        v_audit_data(v_idx).new_salary := :NEW.salary;  
        v_audit_data(v_idx).change_date := SYSDATE;  
    END BEFORE EACH ROW;  

    -- After the statement, insert all audit records in bulk  
    AFTER STATEMENT IS  
    BEGIN  
        FORALL i IN 1..v_idx  
            INSERT INTO salary_audit VALUES v_audit_data(i);  
    END AFTER STATEMENT;  

END trg_salary_audit;

14. Apa itu overloading di PL/SQL?

Overloading memungkinkan beberapa procedure atau function dengan nama yang sama tetapi parameter berbeda didefinisikan dalam satu package. Hal ini meningkatkan keterbacaan dan kemudahan pemeliharaan kode dengan menyediakan beberapa cara untuk melakukan operasi serupa.

Dalam kueri di bawah, badan package mengimplementasikan dua procedure overload bernama update_salary: Satu menaikkan gaji karyawan dengan jumlah tertentu, sementara yang lain menetapkan gaji baru dengan tanggal efektif, memperbarui tabel employees sesuai.

-- Create the package specification
CREATE OR REPLACE PACKAGE emp_pkg AS  
    -- Procedure to increment salary by a specified amount  
    PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER);

    -- Overloaded procedure to set a new salary with an effective date  
    PROCEDURE update_salary(p_emp_id NUMBER, p_new_salary NUMBER, p_effective_date DATE);
END emp_pkg;
/
-- Create the package body
CREATE OR REPLACE PACKAGE BODY emp_pkg AS  

    -- Procedure to increment salary by a specified amount  
    PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER) AS  
    BEGIN  
        UPDATE employees  
        SET salary = salary + p_increment  
        WHERE employee_id = p_emp_id;  
    END update_salary;  

    -- Overloaded procedure to set a new salary with an effective date  
    PROCEDURE update_salary(p_emp_id NUMBER, p_new_salary NUMBER, p_effective_date DATE) AS  
    BEGIN  
        UPDATE employees  
        SET salary = p_new_salary, last_update = p_effective_date  
        WHERE employee_id = p_emp_id;  
    END update_salary;  

END emp_pkg;
/

15. Apa itu direktif kompilator dan pragma di PL/SQL?

PL/SQL menyediakan direktif kompilator (PRAGMA) untuk mengoptimalkan kode dan menangani pengecualian. Pragma umum meliputi:

  • PRAGMA EXCEPTION_INIT: Mengaitkan pengecualian buatan pengguna dengan kode error Oracle.

  • PRAGMA SERIALLY_REUSABLE: Mengoptimalkan penggunaan memori package untuk skalabilitas.

Blok PL/SQL di bawah ini menangani penyisipan karyawan dengan gaji tidak valid menggunakan pengecualian kustom e_invalid_salary yang dipetakan ke kode error -20001. Jika pengecualian dipicu, akan mencetak pesan error.

DECLARE  
    e_invalid_salary EXCEPTION;  -- Declare custom exception for invalid salary  
    PRAGMA EXCEPTION_INIT(e_invalid_salary, -20001);  -- Associate exception with error code -20001  
BEGIN  
    -- Attempt to insert an employee with invalid salary  
    INSERT INTO employees (employee_id, salary) VALUES (999, -1000);  
EXCEPTION  
    -- Handle the custom exception and print a message  
    WHEN e_invalid_salary THEN  
        DBMS_OUTPUT.PUT_LINE('Invalid salary detected!');  
END;  

16. Apa metode berbeda untuk menelusuri dan debug kode PL/SQL?

PL/SQL menyediakan beberapa paket bawaan untuk penelusuran dan debug kinerja kode. Metode umum termasuk menggunakan DBMS_TRACE untuk melacak alur eksekusi, DBMS_APPLICATION_INFO untuk memantau aktivitas sesi, dan DBMS_SESSION untuk mengumpulkan informasi diagnostik tingkat sesi.

Kueri di bawah ini terlebih dahulu mengaktifkan penelusuran SQL menggunakan DBMS_SESSION.set_sql_trace(TRUE), kemudian menetapkan informasi sesi spesifik klien dengan DBMS_APPLICATION_INFO.set_client_info() untuk pemantauan. Blok PL/SQL dieksekusi, yang mensimulasikan operasi UPDATE. Terakhir, penelusuran dinonaktifkan setelah eksekusi menggunakan DBMS_SESSION.set_sql_trace(FALSE).

-- Enable tracing for the current session using DBMS_SESSION
BEGIN
   -- Start session-level tracing
   DBMS_SESSION.set_sql_trace(TRUE);
END;
/

-- Set application information using DBMS_APPLICATION_INFO
BEGIN
   -- Set the application name and action for session monitoring
   DBMS_APPLICATION_INFO.set_client_info('Trace Debug Session');
   DBMS_APPLICATION_INFO.set_action('Debugging PL/SQL Code');
END;
/

-- Example PL/SQL block that simulates a process for debugging
DECLARE
   v_employee_id NUMBER := 100;
BEGIN
   -- Example query to fetch employee details
   FOR rec IN (SELECT first_name, last_name FROM employees WHERE employee_id = v_employee_id) LOOP
      DBMS_OUTPUT.put_line('Employee: ' || rec.first_name || ' ' || rec.last_name);
   END LOOP;
   
   -- Simulate some logic that could be traced
   IF v_employee_id = 100 THEN
      DBMS_OUTPUT.put_line('Employee ID is 100');
   END IF;
END;
/

-- Disable tracing after the session is complete
BEGIN
   -- Stop session-level tracing
   DBMS_SESSION.set_sql_trace(FALSE);
END;
/

Pertanyaan Wawancara PL/SQL Berbasis Skenario

Dalam aplikasi perusahaan dunia nyata, PL/SQL digunakan untuk menangani logika bisnis yang kompleks. Pewawancara sering menilai kemampuan kandidat untuk menerapkan PL/SQL dalam skenario praktis. Di bawah ini beberapa tantangan kunci beserta strategi penyelesaiannya.

Untuk bagian berikutnya sekaligus terakhir, jika Anda yang diwawancarai, saya mendorong Anda untuk memikirkan cara menjawab pertanyaan mengikuti template ini, namun tentu sesuaikan jawaban dengan industri spesifik Anda atau untuk mencerminkan pengalaman Anda sendiri. Hal yang sama berlaku jika Anda mewawancarai kandidat dan membutuhkan ide tentang cara mengajukan pertanyaan dan menilai seberapa menyeluruh jawabannya, yang dalam hal ini saya harap bagian ini menjadi inspirasi untuk pertanyaan dan kriteria evaluasi Anda.

17. Bagaimana Anda merancang trigger di lingkungan dengan konkurensi tinggi?

Asumsikan skenario di mana Anda perlu menegakkan aturan bisnis bahwa gaji seorang karyawan tidak boleh diperbarui lebih dari sekali per hari. Namun, database mengalami tingkat konkurensi transaksi yang tinggi, dan trigger sederhana dapat menyebabkan kontensi atau masalah kinerja.

Alih-alih menggunakan trigger tingkat baris yang menyala untuk setiap pembaruan dan dapat memperlambat kinerja, gunakan trigger tingkat pernyataan dengan tabel log untuk mencegah beberapa pembaruan gaji dalam hari yang sama.

Sebagai contoh, trigger di bawah ini mencegah beberapa pembaruan gaji untuk seorang karyawan pada hari yang sama dengan memeriksa tabel salary_update_log sebelum mengizinkan pembaruan. Jika gaji sudah diperbarui hari ini, akan muncul error; jika tidak, tanggal pembaruan akan dicatat.

-- Create a table to log the last salary update for each employee
CREATE TABLE salary_update_log (
    employee_id NUMBER PRIMARY KEY,  -- Employee ID as primary key
    last_update DATE  -- Date of the last salary update
);

-- Create or replace a compound trigger to prevent multiple salary updates on the same day
CREATE OR REPLACE TRIGGER trg_prevent_multiple_salary_update  
FOR UPDATE OF salary ON employees  
COMPOUND TRIGGER  

    -- Declare a variable to store last salary update date per row
    TYPE emp_log_type IS TABLE OF DATE INDEX BY PLS_INTEGER;
    emp_log emp_log_type;

    BEFORE STATEMENT IS  
    BEGIN  
        -- Load existing salary update logs into memory for reference
        FOR rec IN (SELECT employee_id, last_update FROM salary_update_log) LOOP  
            emp_log(rec.employee_id) := rec.last_update;  
        END LOOP;  
    END BEFORE STATEMENT;  

    BEFORE EACH ROW IS  
    BEGIN  
        -- Check if an entry exists for this employee
        IF emp_log.EXISTS(:NEW.employee_id) THEN  
            -- Validate if salary was updated today
            IF emp_log(:NEW.employee_id) = TRUNC(SYSDATE) THEN  
                RAISE_APPLICATION_ERROR(-20010, 'Salary can only be updated once per day');  
            ELSE  
                -- Update log in memory
                emp_log(:NEW.employee_id) := TRUNC(SYSDATE);  
            END IF;  
        ELSE  
            -- Insert a new log entry into memory
            emp_log(:NEW.employee_id) := TRUNC(SYSDATE);  
        END IF;  
    END BEFORE EACH ROW;  

    AFTER STATEMENT IS  
    BEGIN  
        -- Apply changes to the log table after all row updates
        FOR i IN emp_log.FIRST .. emp_log.LAST LOOP  
            MERGE INTO salary_update_log l  
            USING (SELECT i AS employee_id, emp_log(i) AS last_update FROM DUAL) s  
            ON (l.employee_id = s.employee_id)  
            WHEN MATCHED THEN  
                UPDATE SET l.last_update = s.last_update  
            WHEN NOT MATCHED THEN  
                INSERT (employee_id, last_update) VALUES (s.employee_id, s.last_update);  
        END LOOP;  
    END AFTER STATEMENT;  

END trg_prevent_multiple_salary_update;

Contoh di atas akan mengurangi penguncian tingkat baris dan meminimalkan konflik transaksi selama pembaruan massal.

18. Bagaimana Anda membagi transaksi besar menjadi potongan lebih kecil demi keandalan?

Bayangkan skenario di mana sistem perbankan memerlukan pembaruan massal untuk menyesuaikan suku bunga bagi jutaan rekening nasabah. Menjalankan satu transaksi besar dapat mengunci tabel terlalu lama atau menyebabkan kegagalan rollback.

Untuk kasus ini, gunakan pemrosesan bulk dengan COMMIT bertahap untuk memproses data secara inkremental dan menghindari kontensi.

Blok PL/SQL di bawah ini mengimplementasikan solusi dengan menggunakan BULK COLLECT untuk mengambil ID rekening dan kemudian mengiterasinya untuk memperbarui suku bunga sebesar 5%. Perubahan dikomit setiap 1000 pembaruan untuk meningkatkan kinerja dan mengurangi penggunaan sumber daya. Komit akhir memastikan pembaruan yang tersisa disimpan.

DECLARE  
    -- Define a collection type for account IDs  
    TYPE t_accounts IS TABLE OF NUMBER;  -- Use NUMBER instead of referencing accounts.account_id
    v_account_ids t_accounts;  -- Variable to store account IDs  
    v_batch_size CONSTANT NUMBER := 1000;  -- Batch size for commits  

BEGIN  
    -- Bulk collect all account IDs into the collection  
    SELECT account_id BULK COLLECT INTO v_account_ids FROM accounts;  

    -- Loop through each account ID to update the interest rate  
    FOR i IN 1 .. v_account_ids.COUNT LOOP  
        UPDATE accounts  
        SET interest_rate = interest_rate * 1.05  -- Increase interest rate by 5%  
        WHERE account_id = v_account_ids(i);  

        -- Commit after every 1000 updates  
        IF MOD(i, v_batch_size) = 0 THEN  
            COMMIT;  
        END IF;  
    END LOOP;  

    COMMIT; -- Final commit for any remaining updates  
END;
/

Solusi ini akan memastikan keandalan dalam sistem keuangan seperti penggajian dengan mencegah kegagalan transaksi.

19. Bagaimana Anda mengorganisasi logika kompleks ke dalam package demi kemudahan pemeliharaan?

Sebuah perusahaan ritel perlu menerapkan sistem pemrosesan pesanan yang melibatkan beberapa langkah: Memeriksa ketersediaan inventaris, melakukan reservasi stok, menghitung diskon, dan mencatat riwayat transaksi.

Alih-alih menulis prosedur terpisah yang berdiri sendiri, Anda perlu mengorganisasi logika ini dengan cara yang terstruktur dan mudah dipelihara. Oleh karena itu, gunakan package PL/SQL untuk mengenkapsulasi procedure dan function terkait, sehingga meningkatkan reusabilitas dan kemudahan pemeliharaan kode

Spesifikasi package di bawah ini mendefinisikan function dan procedure untuk pemrosesan pesanan, termasuk memeriksa inventaris, memesan stok, menghitung diskon, dan mencatat status transaksi. Ini memberikan pendekatan modular untuk menangani tugas terkait pesanan.

-- Create a package specification for order processing functions and procedures
CREATE PACKAGE order_processing_pkg AS  

    -- Function to check if enough inventory is available for the product
    FUNCTION check_inventory(p_product_id NUMBER, p_quantity NUMBER) RETURN BOOLEAN;  

    -- Procedure to reserve stock for a specific order
    PROCEDURE reserve_stock(p_order_id NUMBER, p_product_id NUMBER, p_quantity NUMBER);  

    -- Function to calculate discount based on customer and total amount
    FUNCTION calculate_discount(p_customer_id NUMBER, p_total_amount NUMBER) RETURN NUMBER;  

    -- Procedure to log the status of a transaction
    PROCEDURE log_transaction(p_order_id NUMBER, p_status VARCHAR2);  

END order_processing_pkg;

Kemudian kami menggunakan badan package berikut untuk mengimplementasikan function dan procedure yang didefinisikan dalam spesifikasi package. Ini menangani tugas kunci seperti memeriksa ketersediaan inventaris, memesan stok, menghitung diskon, dan mencatat status transaksi, memastikan operasi pemrosesan pesanan berjalan lancar.

-- Create the package body implementing the functions and procedures for order processing
CREATE PACKAGE BODY order_processing_pkg AS  

    -- Function to check if sufficient inventory is available for the product
    FUNCTION check_inventory(p_product_id NUMBER, p_quantity NUMBER) RETURN BOOLEAN AS  
        v_available_qty NUMBER;  -- Variable to store available quantity  
    BEGIN  
        -- Retrieve the available quantity from inventory
        SELECT stock_quantity INTO v_available_qty FROM inventory WHERE product_id = p_product_id;  
        -- Return true if enough stock is available, otherwise false
        RETURN v_available_qty >= p_quantity;  
    END check_inventory;  

    -- Procedure to reserve stock for a specific order
    PROCEDURE reserve_stock(p_order_id NUMBER, p_product_id NUMBER, p_quantity NUMBER) AS  
    BEGIN  
        -- Deduct the ordered quantity from the inventory
        UPDATE inventory SET stock_quantity = stock_quantity - p_quantity WHERE product_id = p_product_id;  
    END reserve_stock;  

    -- Function to calculate a discount based on the total order amount
    FUNCTION calculate_discount(p_customer_id NUMBER, p_total_amount NUMBER) RETURN NUMBER AS  
        v_discount NUMBER := 0;  -- Initialize discount to 0  
    BEGIN  
        -- Apply 10% discount if the total amount is greater than 500
        IF p_total_amount > 500 THEN  
            v_discount := p_total_amount * 0.10;  
        END IF;  
        -- Return the calculated discount
        RETURN v_discount;  
    END calculate_discount;  

    -- Procedure to log the transaction status
    PROCEDURE log_transaction(p_order_id NUMBER, p_status VARCHAR2) AS  
    BEGIN  
        -- Insert a log entry for the order status
        INSERT INTO order_log (order_id, status, log_date) VALUES (p_order_id, p_status, SYSDATE);  
    END log_transaction;  

END order_processing_pkg;

20. Bagaimana Anda menangani deadlock dalam sistem dengan transaksi tinggi?

Asumsikan skenario di mana sistem keuangan sering memperbarui beberapa tabel terkait secara bersamaan. Deadlock terjadi ketika dua transaksi saling menunggu sumber daya yang terkunci satu sama lain, menyebabkan hambatan kinerja.

Untuk mengatasi masalah ini, selalu kuncilah baris dalam urutan yang konsisten di seluruh transaksi. Juga, gunakan klausa NOWAIT atau SKIP LOCKED untuk mencegah penantian tanpa batas.

Sebagai contoh, blok PL/SQL di bawah ini mencoba mengunci baris tertentu di tabel accounts untuk pembaruan menggunakan klausa FOR UPDATE NOWAIT, yang menyebabkan transaksi langsung gagal jika sesi lain sudah mengunci baris tersebut. Setelah mengunci, blok memperbarui status transaksi dan melakukan commit perubahan. Jika terjadi error, pengecualian ditangkap dan pesan error dicetak.

DECLARE  
    v_balance NUMBER(15,2);  -- Declare variable to store the account balance  
BEGIN  
    -- Lock the account row for update to prevent other sessions from modifying it  
    SELECT balance INTO v_balance FROM accounts  
    WHERE account_id = 101 FOR UPDATE NOWAIT;  

    -- Update the transaction status to 'Processed' for all transactions related to this account  
    UPDATE transactions  
    SET status = 'Processed'  
    WHERE account_id = 101 AND status = 'Pending';  -- Update only pending transactions  

    COMMIT;  -- Commit the changes  

EXCEPTION  
    -- Handle errors, such as locking issues or unexpected exceptions  
    WHEN OTHERS THEN  
        DBMS_OUTPUT.PUT_LINE('Transaction failed: ' || SQLERRM);  
        ROLLBACK;  -- Ensure rollback in case of failure  
END;
/

Demikian pula, blok PL/SQL ini memproses transaksi yang tertunda dengan menguncinya untuk pembaruan menggunakan FOR UPDATE SKIP LOCKED, sehingga dapat melewati baris yang sudah dikunci sesi lain. Blok ini memperbarui status setiap transaksi menjadi 'Processing' dan melakukan commit di akhir.

DECLARE  
    -- Declare a cursor to select pending transactions and lock rows for update
    CURSOR c_pending_txns IS  
        SELECT transaction_id FROM transactions WHERE status = 'Pending' FOR UPDATE SKIP LOCKED;  -- Skip locked rows  

BEGIN  
    -- Loop through the pending transactions
    FOR txn IN c_pending_txns LOOP  
        -- Update the status of each transaction to 'Processing'
        UPDATE transactions SET status = 'Processing' WHERE transaction_id = txn.transaction_id;  
    END LOOP;  
    COMMIT;  -- Commit the changes to finalize the transaction updates  
END;

Kesimpulan dan Sumber Tambahan

Untuk peran yang berfokus pada Oracle, pemberi kerja mencari kandidat yang dapat menulis kode PL/SQL dengan benar, menangani tantangan nyata, dan mengoptimalkan kinerja database. Saya merekomendasikan untuk memeriksa dokumentasi resmi Oracle tentang PL/SQL Language Reference untuk panduan mendalam dan praktik terbaik seputar PL/SQL. Oracle Live SQL (Interactive PL/SQL Playground) menyediakan akses ke platform berbasis cloud Oracle untuk menjalankan kueri PL/SQL secara online. Saya juga mendorong Anda bergabung dengan Oracle Community untuk berinteraksi dengan pakar dan pengembang Oracle serta forum Stack Overflow untuk menemukan solusi atas pertanyaan terkait PL/SQL.

Namun, tidak ada yang mengalahkan jalur belajar terstruktur. Karena itu, saya sangat, sangat merekomendasikan mengikuti kursus Introduction to Oracle SQL kami, yang menurut saya benar-benar cara terbaik untuk menjadi ahli. Juga, jika Anda ingin meningkatkan pengetahuan dalam bekerja dengan database, saya sarankan mengikuti kursus Database Design kami, di mana Anda akan belajar membuat dan mengelola database serta memilih DBMS yang sesuai dengan kebutuhan Anda. Terakhir, coba jalur karier Associate Data Engineer in SQL untuk mempelajari dasar-dasar rekayasa data dan data warehouse. 

Terakhir namun tidak kalah penting, jika Anda sedang mewawancarai kandidat dan juga ingin meningkatkan keterampilan orang lain, hubungi tim DataCamp for Business kami. DataCamp dapat meningkatkan keterampilan seluruh tim dengan proyek praktis dan jalur pembelajaran kustom. Ini adalah cara yang bagus bagi pemberi kerja untuk menjembatani kesenjangan keterampilan dan meningkatkan kepercayaan diri serta kredibilitas tim, jadi hubungi tim kami hari ini.


Allan Ouko's photo
Author
Allan Ouko
LinkedIn
Penulis teknis Data Science dengan pengalaman langsung dalam analitik data, business intelligence, dan data science. Saya menulis konten praktis berfokus industri tentang SQL, Python, Power BI, Databricks, dan rekayasa data, yang berakar pada pekerjaan analitik dunia nyata. Tulisan saya menjembatani kedalaman teknis dan dampak bisnis, membantu para profesional mengubah data menjadi keputusan yang meyakinkan.

FAQ PL SQL

Apa itu PL/SQL, dan bagaimana perbedaannya dengan SQL?

PL/SQL adalah bahasa prosedural yang dikembangkan oleh Oracle, memungkinkan struktur kontrol dan penanganan error, sedangkan SQL bersifat deklaratif dan menangani pengambilan/manipulasi data.

Apa itu package PL/SQL?

Kumpulan procedure, function, variabel, dan cursor yang terkait untuk pemrograman modular dan reusabilitas.

Bagaimana perbedaan procedure dengan function?

Procedure melakukan aksi yang tidak mengembalikan nilai, sedangkan function mengembalikan nilai yang dapat digunakan dalam kueri.

Apa itu trigger dalam PL/SQL?

Aksi otomatis yang dieksekusi sebelum atau sesudah operasi INSERT, UPDATE, DELETE.

Apa itu pemrosesan bulk di PL/SQL?

Pemrosesan bulk (BULK COLLECT, FORALL) meningkatkan kinerja dengan mengurangi perpindahan konteks antara mesin PL/SQL dan SQL saat menangani dataset besar.

Topik

Belajar SQL dengan DataCamp

Kursus

Manipulasi Data di SQL

4 Hr
317K
Kuasai kueri SQL yang kompleks yang diperlukan untuk menjawab berbagai pertanyaan ilmu data dan menyiapkan set data yang kuat untuk analisis di PostgreSQL.
Lihat DetailRight Arrow
Mulai Kursus
Lihat Lebih BanyakRight Arrow
Terkait

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

12 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

Lihat Lebih BanyakLihat Lebih Banyak