Fitur LastInsertID (MySQL) Dan Returning (PostgreSQL) Pada Data Master-Detail
| September 28, 2012 | Posted by Joko Rivai under Database, Delphi, Tips & Tricks |
Dalam pemrograman database MySQL dengan Delphi, atau pemrograman aplikasi Delphi dengan database PostgreSQL, kedua fitur di atas akan menjadi penting dan sangat bermanfaat. Untuk melihat manfaat LastInsertID dan Returning ini, kita anggap bahwa kita punya dua tabel, yaitu tabel “ref_jenis_jurnal” yang menjadi tabel master:
CREATE TABLE `ref_jenis_jurnal` ( `id` INT(8) NOT NULL AUTO_INCREMENT, `jenis` VARCHAR(200) NOT NULL, `keterangan` TEXT NULL, `tabel` VARCHAR(50) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB AUTO_INCREMENT=5;
Dan sebuah tabel lagi, “ref_jenis_jurnal_rek” yang menjadi tabel detail:
CREATE TABLE `ref_jenis_jurnal_rek` (
`id` INT(8) NOT NULL AUTO_INCREMENT,
`jenis_jurnal` INT(8) NOT NULL,
`rek` VARCHAR(7) NOT NULL,
`posisi` ENUM('D','K') NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK__ref_jenis_jurnal` (`jenis_jurnal`),
CONSTRAINT `FK__ref_jenis_jurnal` FOREIGN KEY (`jenis_jurnal`) REFERENCES `ref_jenis_jurnal` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=14;
Nah, dari aplikasi Delphi, user dibolehkan membuat sebuah record untuk tabel “ref_jenis_jurnal” sekaligus record-record yang menjadi detailnya di tabel “ref_jenis_jurnal_rek”. Saat di-save nanti, yang pertama kita lakukan adalah memasukkan record master ke tabel master, lalu mengambil nilai field ref_jenis_jurnal.id untuk nanti dijadikan value pada field detail ref_jenis_jurnal_rek.jenis_jurnal.
Pertanyaannya, bagaimanakah kita mendapatkan nilai field ref_jenis_jurnal.id ini saat proses menyimpan data?
Di MySQL, setiap proses insert data ke tabel yang memiliki field primary auto_increment akan mengubah variabel global session LAST_INSERT_ID yang dapat diambil dengan fungsi MySQL “LAST_INSERT_ID()”.Di Delphi, fungsi ini tidak perlu kita panggil manual, karena banyak vendor 3rd party VCL Components sudah mendukungnya:
- UniDac (Devart) telah mendukungnya dengan TUniTable.LastInsertID dan TUniQuery.LastInsertID;
- MyDac (Devart) pun mendukungna dengan TMyTable.InsertID dan TMyQuery.InsertID;
Contoh penggunaan property LastInsertID pada UniDac dapat dilihat pada contoh kode berikut. Penggunaan pada MyDac tidak jauh berbeda.
procedure TForm1.Button1Click(Sender: TObject);
var
ID: Int64;
begin
UniTable1.TableName := 'ref_jenis_jurnal';
UniTable1.Open;
UniTable1.Append;
UniTable1.FieldByName('jenis').AsString := 'Jurnal Pembayaran Listrik & PDAM';
//..............
UniTable1.Post;
ID := UniTable1.LastInsertId;
end;
Dari situ, kita bisa melakukan insert untuk record-record detail dengan cara:
//save reord detail:
UniTable2.TableName := 'ref_jenis_jurnal_rek';
UniTable2.Open;
UniTable2.Append;
UniTable2.FieldByName('jenis_jurnal').AsInteger := ID;
//..............
UniTable2.Post;
Pertanyaan lain akan timbul: Apakah tidak akan terjadi tabrakan pada fungsi LAST_INSERT_ID() ini? Di saat bersamaan dengan waktu kita melakukan insert ke tabel master, ternyata ada user lain yang juga melakukan insert ke tabel yang sama. Nilai mana yang akan dihasilkan oleh LAST_INSERT_ID()?
Jangan khawatir. MySQL memiliki mekanisme locking yang bagus sampai ke level record. Dan setiap koneksi yang berbeda akan diidentifikasi oleh MySQL sebagai session yang berbeda pula. Meskipun proses insert dilakukan oleh dua user pada saat yang persis sama, di server MySQL sendiri akan dilihat sebagai dua session yang berlainan, dan MySQL akan memilih salah satu session untuk diproses duluan, sementara yang lain akan disimpan dulu di cache. Saat salah satu session diproses dan yang lain menunggu inilah yang disebut locking (penguncian). Dengan mekanisme locking dan session ini, nilai field ref_jenis_jurnal.id yang dikembalikan oleh fungsi LAST_INSERT_ID() dijamin unik dan berbeda pada setiap session koneksi.
Kemudian, apakah PostgreSQL memiliki konsep yang sama? Sayang sekali, tidak!
Lho, sebuah server database yang disebut-sebut sebagai versi open source dari Oracle kok kalah sama MySQL? Tidak juga. PostgreSQL memiliki cara lain untuk menangani “insertion ID ” ini. Bahkan lebih canggih daripada yang ditawarkan MySQL. Untuk melihat seberapa canggih fitur PostgreSQL yang satu ini, silahkan perhatikan gambar di bawah:
Klik di sini agar mendapatkan sedikit gambaran.
Sudah fresh? Ok, kita lanjut.
Di PostgreSQL, tersedia sebuah keyword returning yang bersifat opsional saat kita melakukan insert ke tabel menggunakan query. Sayang sekali, kita akan sedikit kerepotan bila menggunakan komponen TDataset dan turunannya (TUniTable, TMyQuery, dsb.) untuk menginsert data. Tapi tidak masalah, karena saya pikir bahwa sebagai programmer Delphi berpengalaman, Anda akan memilih query untuk menginsert data, bukan TDataset. Tidak seperti saya yang kerjanya asal jadi
fitur Returning ini dapat kita gunakan seperti ini:
procedure TForm1.Button2Click(Sender: TObject); var ID: Int64; begin //................. UniQuery1.SQL.Text := 'insert into ref_jenis_jurnal(jenis,...,...) values (...,...,...) returning id'; UniQuery1.Open; ID := UniQuery1.Fields[0].AsInteger; UniQuery1.Close; //................. end;
Lihat perintah insert SQL pada kode di atas? Ada “returning id” pada SQL itu. Maksudnya, begitu perintah insert berhasil, nilai field “id” yang baru dikembalikan lagi ke aplikasi kita. Kita dapat mengambil nilai ini dengan kode
ID := UniQuery1.Fields[0].AsInteger;
//atau:
ID := UniQuery1.FieldByName('id').AsInteger;
Canggihnya, kita bahkan bisa melakukan return terhadapt field-field lain yang bukan auto_increment. Sembarang field lah pokoknya. Lebih hebat lagi, kita dapat me-return beberapa field sekaligus:
procedure TForm1.Button2Click(Sender: TObject); var ID: Int64; Jenis: String; begin //................. UniQuery1.SQL.Text := 'insert into ref_jenis_jurnal(jenis,...,...) values (...,...,...) returning id, jenis'; UniQuery1.Open; ID := UniQuery1.Fields[0].AsInteger; Jenis := UniQuery1.Fields[1].AsString; UniQuery1.Close; //................. end;
Tinggal kita sesuaikan saja dengan kebutuhan kita. MySQL atau PostgreSQL? Itu urusan Anda, silahkan sesuaikan kebutuhan dan tingkat kompleksitas database yang Anda perlukan.
Salam sayang, eh salam cinta, eh.. Salam hangat
Incoming search terms:
- bisyar
- insert data delphi ke postgre
- bispak makassar
- hapus data master dan detail sekaligus
- mydac unidac bersamaan
- perintah insert mysql untuk 2 tabel master detail
- mengakses store procedure postgresql di vb net
- jurnal delphi langkah menyimpan data
- janda bisjar
- perintah perintah query mysql dengan delphi menggunakan unidac
Comments
Powered by Facebook Comments









This is the default footer layout. You can easily add or remove columns in the footer.