-- 1. Tanggal dan waktu sekarang SELECT NOW() AS sekarang, CURDATE() AS hari_ini, CURTIME() AS jam_ini;
-- 2. Komponen dari tanggal SELECT tgl_pinjam, YEAR(tgl_pinjam) AS tahun, MONTH(tgl_pinjam) AS bulan, DAY(tgl_pinjam) AS hari, DAYNAME(tgl_pinjam) AS nama_hari FROM peminjaman;
-- 3. Hitung lama peminjaman dalam hari SELECT a.nama, b.judul, p.tgl_pinjam, p.tgl_kembali, DATEDIFF(p.tgl_kembali, p.tgl_pinjam) AS lama_hari FROM peminjaman p JOIN anggota a ON p.id_anggota = a.id_anggota JOIN buku b ON p.id_buku = b.id_buku;
-- 4. Tambahkan 14 hari dari tanggal pinjam (deadline) SELECT tgl_pinjam, DATE_ADD(tgl_pinjam, INTERVAL14DAY) AS deadline_kembali FROM peminjaman;
-- 5. Format tampilan tanggal SELECT tgl_pinjam, DATE_FORMAT(tgl_pinjam, '%d %M %Y') AS format_indo, DATE_FORMAT(tgl_pinjam, '%d/%m/%Y') AS format_slash FROM peminjaman;
-- 6. Hitung keterlambatan SELECT a.nama, b.judul, p.tgl_kembali AS seharusnya, CURDATE() AS hari_ini, GREATEST(0, DATEDIFF(CURDATE(), p.tgl_kembali)) AS hari_terlambat, GREATEST(0, DATEDIFF(CURDATE(), p.tgl_kembali)) *1000AS denda_rp FROM peminjaman p JOIN anggota a ON p.id_anggota = a.id_anggota JOIN buku b ON p.id_buku = b.id_buku WHERE p.status ='dipinjam';
-- 1. Hitung jumlah buku, anggota, dan peminjaman SELECT (SELECTCOUNT(*) FROM buku) AS total_buku, (SELECTCOUNT(*) FROM anggota) AS total_anggota, (SELECTCOUNT(*) FROM peminjaman) AS total_peminjaman;
-- 2. Statistik stok buku SELECT COUNT(*) AS jumlah_judul, SUM(stok) AS total_stok, AVG(stok) AS rata_stok, MAX(stok) AS stok_max, MIN(stok) AS stok_min FROM buku;
-- 3. Jumlah peminjaman per anggota SELECT a.nama, COUNT(p.id_pinjam) AS total_pinjam FROM anggota a LEFTJOIN peminjaman p ON a.id_anggota = p.id_anggota GROUPBY a.id_anggota, a.nama ORDERBY total_pinjam DESC;
-- 4. Jumlah buku per kategori SELECT k.nama_kat, COUNT(b.id_buku) AS jumlah_buku, AVG(b.stok) AS rata_stok FROM kategori k LEFTJOIN buku b ON k.id_kategori = b.id_kategori GROUPBY k.id_kategori, k.nama_kat;
-- 5. Anggota yang meminjam lebih dari 1 buku (HAVING) SELECT a.nama, COUNT(p.id_pinjam) AS total_pinjam FROM anggota a JOIN peminjaman p ON a.id_anggota = p.id_anggota GROUPBY a.id_anggota, a.nama HAVINGCOUNT(p.id_pinjam) >1;
π§βπ» LATIHAN 4 β Stored Procedure Tanpa Parameter
-- Procedure untuk menampilkan semua buku CREATEPROCEDURE sp_tampil_semua_buku() BEGIN SELECT b.isbn, b.judul, b.penulis, k.nama_kat AS kategori, b.stok FROM buku b JOIN kategori k ON b.id_kategori = k.id_kategori ORDERBY b.judul; END//
-- Procedure untuk statistik perpustakaan CREATEPROCEDURE sp_statistik() BEGIN SELECT'Statistik Perpustakaan'AS info;
SELECTCOUNT(*) AS total_buku FROM buku; SELECTCOUNT(*) AS total_anggota FROM anggota; SELECTCOUNT(*) AS peminjaman_aktif FROM peminjaman WHERE status ='dipinjam'; SELECTCOUNT(*) AS buku_habis FROM buku WHERE stok =0; END//
-- Parameter IN: cari buku berdasarkan keyword judul CREATEPROCEDURE sp_cari_buku(IN p_keyword VARCHAR(100)) BEGIN SELECT isbn, judul, penulis, stok FROM buku WHERE judul LIKE CONCAT('%', p_keyword, '%') OR penulis LIKE CONCAT('%', p_keyword, '%'); END//
-- Parameter IN + OUT: tambah peminjaman dan kembalikan ID CREATEPROCEDURE sp_pinjam_buku( IN p_id_anggota INT, IN p_id_buku INT, OUT p_id_pinjam INT, OUT p_pesan VARCHAR(200) ) BEGIN DECLARE v_stok INTDEFAULT0;
-- Cek stok buku SELECT stok INTO v_stok FROM buku WHERE id_buku = p_id_buku;
IF v_stok >0THEN -- Kurangi stok UPDATE buku SET stok = stok -1WHERE id_buku = p_id_buku;
SET p_id_pinjam = LAST_INSERT_ID(); SET p_pesan ='Peminjaman berhasil!'; ELSE SET p_id_pinjam =0; SET p_pesan ='Stok buku habis, tidak bisa dipinjam!'; END IF; END//
-- Procedure untuk mengembalikan buku CREATEPROCEDURE sp_kembalikan_buku( IN p_id_pinjam INT, OUT p_denda INT, OUT p_pesan VARCHAR(200) ) BEGIN DECLARE v_tgl_kembali DATE; DECLARE v_id_buku INT; DECLARE v_hari_telat INTDEFAULT0;
SELECT tgl_kembali, id_buku INTO v_tgl_kembali, v_id_buku FROM peminjaman WHERE id_pinjam = p_id_pinjam;
SET v_hari_telat = GREATEST(0, DATEDIFF(CURDATE(), v_tgl_kembali));
-- Update status peminjaman UPDATE peminjaman SET status = IF(v_hari_telat >0, 'terlambat', 'dikembalikan'), tgl_kembali_aktual = CURDATE() WHERE id_pinjam = p_id_pinjam;
-- Kembalikan stok buku UPDATE buku SET stok = stok +1WHERE id_buku = v_id_buku;
SET p_denda = v_hari_telat *1000; SET p_pesan = IF(v_hari_telat >0, CONCAT('Terlambat ', v_hari_telat, ' hari. Denda: Rp ', v_hari_telat *1000), 'Buku dikembalikan tepat waktu. Terima kasih!'); END//
-- Buat tabel log untuk mencatat aktivitas CREATETABLE log_aktivitas ( id_log INT AUTO_INCREMENT PRIMARY KEY, tabel_terkait VARCHAR(50), aksi ENUM('INSERT','UPDATE','DELETE'), id_record INT, keterangan TEXT, waktu DATETIME DEFAULT NOW() );
DELIMITER //
-- Trigger: catat setiap peminjaman baru CREATETRIGGER trg_after_insert_pinjam AFTER INSERTON peminjaman FOREACHROW BEGIN INSERTINTO log_aktivitas (tabel_terkait, aksi, id_record, keterangan) VALUES ('peminjaman', 'INSERT', NEW.id_pinjam, CONCAT('Anggota ID=', NEW.id_anggota, ' meminjam Buku ID=', NEW.id_buku)); END//
-- Trigger: cegah peminjaman jika stok habis (BEFORE INSERT) CREATETRIGGER trg_before_insert_pinjam BEFORE INSERTON peminjaman FOREACHROW BEGIN DECLARE v_stok INT; SELECT stok INTO v_stok FROM buku WHERE id_buku = NEW.id_buku;
IF v_stok <=0THEN SIGNAL SQLSTATE'45000' SET MESSAGE_TEXT ='ERROR: Stok buku habis, tidak bisa dipinjam!'; END IF; END//
-- Trigger: update status peminjaman menjadi terlambat otomatis CREATETRIGGER trg_before_update_pinjam BEFORE UPDATEON peminjaman FOREACHROW BEGIN IF NEW.tgl_kembali_aktual ISNOTNULLAND OLD.status ='dipinjam'THEN IF NEW.tgl_kembali_aktual > OLD.tgl_kembali THEN SET NEW.status ='terlambat'; ELSE SET NEW.status ='dikembalikan'; END IF; END IF; END//
-- Trigger: catat perubahan data anggota CREATETRIGGER trg_after_update_anggota AFTER UPDATEON anggota FOREACHROW BEGIN INSERTINTO log_aktivitas (tabel_terkait, aksi, id_record, keterangan) VALUES ('anggota', 'UPDATE', NEW.id_anggota, CONCAT('Data diubah: nama [', OLD.nama, ' β ', NEW.nama, ']')); END//
-- SOAL 1: -- Buat procedure sp_laporan_harian(IN p_tanggal DATE) -- yang menampilkan: -- a. Total buku dipinjam pada tanggal tersebut -- b. Total buku dikembalikan pada tanggal tersebut -- c. Daftar anggota yang masih meminjam dengan status terlambat
-- SOAL 2: -- Buat procedure sp_perpanjang_pinjam(IN p_id_pinjam INT, IN p_hari_tambah INT) -- yang memperpanjang tanggal kembali sebanyak p_hari_tambah hari -- Hanya bisa diperpanjang maksimal 1 kali
-- SOAL 3: -- Buat trigger trg_after_delete_anggota -- yang mencatat ke log_aktivitas setiap kali data anggota dihapus
-- SOAL 4: -- Buat function (bukan procedure) untuk menghitung denda: -- CREATE FUNCTION fn_hitung_denda(p_id_pinjam INT) RETURNS INT -- Kembalikan total denda dalam rupiah (Rp 500/hari)