trigger insert/update

80 views
Skip to first unread message

selfe...@gmail.com

unread,
Feb 20, 2009, 7:51:14 AM2/20/09
to mysql-i...@googlegroups.com
Hello mysql-indonesia,

Saya lagi coba bikin trigger untuk update data.
tiap kali insert data ke file tbldtljurnal selalu keluar error
explici or implicit commit is not allowed is stored function or
trigger.

udah benar kah caranya mengkaitkan dua buah file header dan detil,
pakai sp.
mohon solusinya.
tks

file trigger

DELIMITER $$

DROP TRIGGER /*!50032 IF EXISTS */ `dblintas`.`tr_insert_jurnal`$$

CREATE
/*!50017 DEFINER = 'root'@'localhost' */
TRIGGER `dblintas`.`tr_insert_jurnal` AFTER INSERT ON `dblintas`.`tbldtljurnal`
FOR EACH ROW BEGIN
call mk_tbljurnalsem();
INSERT INTO tbljurnalsem set no_acct=New.no_acct, tanggal=tblhdrjurnal.tanggal,
t_db=NEW.t_db, t_cr=NEW.t_cr;
CASE
WHEN MONTH(tbljurnalsem.tanggal) = 1 AND NEW.t_cr > 0 THEN
UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;
WHEN MONTH(tbljurnalsem.tanggal) = 1 AND NEW.t_db > 0 THEN
UPDATE tblchat set cr_01 = NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;
WHEN MONTH(tbljurnalsem.tanggal) = 2 AND NEW.t_cr > 0 THEN
UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;
WHEN MONTH(tbljurnalsem.tanggal) = 2 AND NEW.t_db > 0 THEN
UPDATE tblchat set cr_01 = NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;
END CASE;

END;
$$

DELIMITER ;


file procesur
DELIMITER $$

DROP PROCEDURE IF EXISTS `dblintas`.`mk_tbljurnalsem`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `mk_tbljurnalsem`()
BEGIN
drop table if exists tbljurnalsem;
create table tbljurnalsem(no_acct varchar(28), tanggal date, t_db numeric(14,2), t_cr numeric(14,2));
/*INSERT INTO tbljurnalsem (SELECT a.no_acct, b.tanggal, a.t_db, a.t_cr FROM tbldtljurnal AS a,
tblhdrjurnal AS b WHERE a.no_dok = b.no_dok); */
END$$

DELIMITER ;

--
Best regards,
selfersoft
mailto:selfe...@gmail.com

Fajar A. Nugraha

unread,
Feb 20, 2009, 8:07:58 AM2/20/09
to mysql-i...@googlegroups.com
On Fri, Feb 20, 2009 at 7:51 PM, <selfe...@gmail.com> wrote:
> Saya lagi coba bikin trigger untuk update data.
> tiap kali insert data ke file tbldtljurnal selalu keluar error
> explici or implicit commit is not allowed is stored function or
> trigger.

> file procesur


> DELIMITER $$
>
> DROP PROCEDURE IF EXISTS `dblintas`.`mk_tbljurnalsem`$$
>
> CREATE DEFINER=`root`@`localhost` PROCEDURE `mk_tbljurnalsem`()
> BEGIN
> drop table if exists tbljurnalsem;

http://mysql.openmirrors.org/doc/refman/5.1/en/implicit-commit.html
drop table melakukan implicit commit, dan akibatnya tidak diizinkan
berada dalam prosedur.

--
FAN

Rizky Prihanto

unread,
Feb 20, 2009, 8:15:03 AM2/20/09
to mysql-i...@googlegroups.com
Di dalam stored procedure sebenarnya bisa melakukan explicit atau implicit commit-rollback. Tapi di dalam Stored Function dan Trigger gag bisa.

Dan kalo dalam trigger di kasus Anda memanggil SP yang terdapat restriction2 thdp trigger, ya tetep ngga bisa.

Untuk mengetahui apa aja limitasi di SF/trigger, plz refer to this : http://mysql.openmirrors.org/doc/refman/5.1/en/routine-restrictions.html

Note that although some restrictions normally apply to stored functions and triggers but not to stored procedures, those restrictions do apply to stored procedures if they are invoked from within a stored function or trigger. For example, although you can use FLUSH in a stored procedure, such a stored procedure cannot be called from a stored function or trigger.


--
regards,

Rizky Prihanto
http://rizky.prihanto.web.id
Phone #1 : 0812 535 22 392
Phone #2 : 0856 496 00 496

selfe...@gmail.com

unread,
Feb 20, 2009, 5:37:38 PM2/20/09
to Fajar A. Nugraha
Hello Fajar,
Friday, February 20, 2009, 9:07:58 PM, you wrote:

Masih nggak ngerti pak, terus solusinya bagaimana pak.
atau nggak perlu pakai table sementara, bisa nggak langsung update ke
file tblchat dari table tblhdrjurnal dan tbldtljurnal nya pak
tks.


--

Fajar A. Nugraha

unread,
Feb 20, 2009, 10:15:16 PM2/20/09
to mysql-i...@googlegroups.com
2009/2/21 <selfe...@gmail.com>:

> Masih nggak ngerti pak, terus solusinya bagaimana pak.
> atau nggak perlu pakai table sementara, bisa nggak langsung update ke
> file tblchat dari table tblhdrjurnal dan tbldtljurnal nya pak
> tks.

Tergantung logic aplikasinya gimana :) Mohon maaf, saya gak bisa bantu
banyak di sini karna mempelajari logic aplikasi bisa butuh waktu
panjang. Tapi kalo diliihat sekilas sih kayaknya tbljurnalsem isinya
cuma satu row ya? Mestinya kamu bisa pake SELECT INTO ke variabel.
Jadi ganti penggunaan tabel sementara (tbljurnalsem) dengan variabel.

http://dev.mysql.com/doc/refman/5.1/en/user-variables.html
http://dev.mysql.com/doc/refman/5.1/en/select-into-statement.html

Kalo masih butuh bantuan lebih lanjut (untuk implementasi langsung
misalnya), mungkin RQ atau rekan lain bisa memberikan rekomendasi
kenalan yang bisa memberikan professional assistance :)

PS : mysql-i...@googlegroups.com itu email addressnya MySQL
Indonesia lho, bukan email address saya lho. Kayaknya address book-mu
mesti diupdate

--
FAN

selfe...@gmail.com

unread,
Feb 21, 2009, 9:37:28 PM2/21/09
to mysql-i...@googlegroups.com
Hello,
Saturday, February 21, 2009, 11:15:16 AM, you wrote:

Saya bingung ini milis atau help ajak mysql indonesia ya ?
tiap kali bertanya selalu disuruh baca ref manual nya mysql.
karena belum ngerti di ref nya makanya tanya ke sini.

emang hanya buruh 1 row, oh bisa pakai variabel.
saya baca help dulu, kenapa milis ini nggak bisa kasih contoh sedikit
untuk kita2 yang baru ngenal mysql

> http://dev.mysql.com/doc/refman/5.1/en/user-variables.html
> http://dev.mysql.com/doc/refman/5.1/en/select-into-statement.html


--

Fajar A. Nugraha

unread,
Feb 21, 2009, 10:54:52 PM2/21/09
to mysql-i...@googlegroups.com
2009/2/22 <selfe...@gmail.com>:

> Saya bingung ini milis atau help ajak mysql indonesia ya ?
> tiap kali bertanya selalu disuruh baca ref manual nya mysql.

... karena hal yang Anda tanyakan sudah dibahas cukup lengkap di ref
manualnya Om, dengan penjelasan dan contoh yang cukup lengkap.

> karena belum ngerti di ref nya makanya tanya ke sini.
>

Jika memang begitu akan lebih membantu jika Anda sebutkan bagian mana
yang belum dimengerti. Untuk pertanyaan tentang "explicit or implicit
commit is not allowed", maupun workaroundnya, IMHO penjelasan paling
lengkap justru ada ref manual juga.

> emang hanya buruh 1 row, oh bisa pakai variabel.
> saya baca help dulu, kenapa milis ini nggak bisa kasih contoh sedikit
> untuk kita2 yang baru ngenal mysql
>

Untuk pengunaan variabel, contohnya juga udah ada juga di manual.
Silakan dicoba dulu, jika menemukan kesulitan bisa diposting lagi di
sini. Mestinya sih trigger Anda tidak perlu menggunakan temporary
table dan procedure lagi.

--
FAN

Rizky Prihanto

unread,
Feb 21, 2009, 11:45:06 PM2/21/09
to mysql-i...@googlegroups.com
CREATE TRIGGER `dblintas`.`tr_insert_jurnal` AFTER INSERT ON `dblintas`.`tbldtljurnal`

   FOR EACH ROW BEGIN
   call mk_tbljurnalsem();
   INSERT INTO tbljurnalsem set no_acct=New.no_acct, tanggal=tblhdrjurnal.tanggal,
                                t_db=NEW.t_db, t_cr=NEW.t_cr;
   CASE
     WHEN MONTH(tbljurnalsem.tanggal) = 1 AND NEW.t_cr > 0 THEN
        UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;
     WHEN MONTH(tbljurnalsem.tanggal) = 1 AND NEW.t_db > 0 THEN
        UPDATE tblchat set cr_01 = NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;
     WHEN MONTH(tbljurnalsem.tanggal) = 2 AND NEW.t_cr > 0 THEN
        UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;
     WHEN MONTH(tbljurnalsem.tanggal) = 2 AND NEW.t_db > 0 THEN
        UPDATE tblchat set cr_01 = NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;
   END CASE;
END;

*mencoba nge-trace* isi trigger elo, gw bingung bro (entah apa gw yg goblok mgkn kali ye?) -- maksut nya loe bikin trigger ini supaya bisa ngapain sih?

cerita dikit dulu dunks...

yang jelas, pendekatan loe utk nyelesai-in masalah dengan create/drop table seperti di atas itu "ditolak ama MySQL" -- jadi musti cari pendekatan lain (yang salah satunya disarankan ama Bang Fajar adalah dengan pakae variabel). Tapi kita2 di sini gag bisa ngasih loe solusi FRONTAL (misal : tanya script dibalas dengan script) karena kita gag tau ceritanya bro...

makanya, cerita dikit dulu dunks tentang maksud dan tujuan loe dalam ngebikin trigger itu...

tentang script elo :
[SATU]

   INSERT INTO tbljurnalsem set no_acct=New.no_acct, tanggal=tblhdrjurnal.tanggal,
                                t_db=NEW.t_db, t_cr=NEW.t_cr;

gw bingung, darimana loe dapat value tblhdrjurnal.tanggal tanpa ada process SELECT? kalo NEW.no_acct dan NEW-NEW yang lain kan jelas tuh dapatnya dari variabel yg di-assign di INSERT loe..

[DUA]

CASE
     WHEN MONTH(tbljurnalsem.tanggal) = 1 AND NEW.t_cr > 0 THEN
        UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;

lagi-lagi gw bingung. kapan loe nge-ambil nilai tbljurnalsem.tanggal ? habis query insert into, loe langsung case coyy... kyanya loe musti pahamin konsep di pemrograman internal DBMS kalo "untuk mengambil" sebuah nilai kolom dari sebuah record di sebuah tabel --> loe musti retreive dulu dengan SELECT.

[TIGA]
gw mencoba sotoy nih dengan *sok-sok* paham ama latar belakang dan maksut loe nge-trigger tsb. Gw coba bikin script trigger yg *semoga* bisa sesuai dengan ekspektasi loe :

CREATE TRIGGER `dblintas`.`tr_insert_jurnal` AFTER INSERT ON `dblintas`.`tbldtljurnal`
   FOR EACH ROW BEGIN
/*
  code loe ini gw hapus/kagak gw pakae :
   call mk_tbljurnalsem();

   INSERT INTO tbljurnalsem set no_acct=New.no_acct, tanggal=tblhdrjurnal.tanggal,
                                t_db=NEW.t_db, t_cr=NEW.t_cr;
*/
/*
  gw coba nangkep, loe pengen "menyamakan" tanggal di jurnal loe dengan tanggal di header jurnal. klo hanya itu doank, loe gag usah bikin temporary tabel segala coyy..
*/
   SELECT tblhdrjurnal.tanggal INTO @tgl
   FROM tblhdrjurnal
   WHERE tblhdrjurnal.no_acct = NEW.no_acct;
/*
  nah, di atas situ letak ke-*sotoy*-an gw. mana gw tau struktur tabel tblhdrjurnal loe seperti apa. dan key penghubung antara tblhdrjurnal dengan tbldtljurnal yg loe INSERT ini pakae field apaan. gw asumsikan aja pakae key no_acct.
*/

   CASE
 
     WHEN MONTH(@tgl) = 1 AND NEW.t_cr > 0 THEN
        UPDATE tblchat SET cr_01 = NEW.t_cr
        WHERE tblchat.no_acct =
NEW.no_acct;
     WHEN MONTH(@tgl) = 1 AND NEW.t_db > 0 THEN
        UPDATE tblchat SET cr_01 = NEW.t_db
       
WHERE tblchat.no_acct = NEW.no_acct;
     WHEN MONTH(@tgl) = 2 AND NEW.t_cr > 0 THEN
        UPDATE tblchat SET cr_01 = NEW.t_cr
       
WHERE tblchat.no_acct = NEW.no_acct;
     WHEN MONTH(@tgl) = 2 AND NEW.t_db > 0 THEN
        UPDATE tblchat SET cr_01 = NEW.t_db
       
WHERE tblchat.no_acct = NEW.no_acct;
     ELSE
       BEGIN  END;
   END CASE;
/*
  gw ganti search condition dari CASE loe pakae MONTH(@tgl)
  n gw tambahin ELSE dengan empty compound statement supaya gag muncul error seperti yg diinformasikan ama MySQL manual halaman ini
*/
END;

[EMPAT]
loe beruntung gw lagi happy nih hari ini -- jadi gw kagak tersinggung ama kata-kata loe yg ini :

selfersoft wrote:
Saya bingung ini milis atau help ajak mysql indonesia ya ?
tiap kali bertanya selalu disuruh baca ref manual nya mysql.

coba loe ikut channel #mysql di irc.freenode.net (bukan #mysql-id loo... itu channel kita) -- di sana klo loe tanyakan sesuatu yg "jelas udah ada" di MySQL manual, mereka gag bakal respon. Bahkan mereka udah kagak mau lagi kasih LINK ke section Manual yg mana (padahal ada 2709 halaman di MySQL Reference Manual yg harus di-telusurin).

Kebanyakan orang ya seperti itu... Bahkan bukan utk urusan CODING saja.
Loe tanya ustadz, beliau akan mengangkat hikmah-hikmah dari salah satu ayat Al-Qur'an.
Loe tanya pendeta, beliau mgkn akan membacakan dulu salah satu ayat dari Al Kitab.
Bahkan loe jadi tukang bangunan aja, loe tanya sesuatu ke mandor elo terkait seputar teknis bangunan -- mandor elo juga bakal buka blueprint yg udah dijelaskan arsitek kepada ntu mandor.

RTFM : Read The FAQs & Manuals
(gw ganti kata2 FUCK dengan FAQ -- frequently asked questions --> karna tampaknya lebih sopan dan lebih relevan)

Jadi, mustinya berbahagialah ente karna masih ada orang2 seperti Bang Fajar Arief Nugroho yang ngasih link spesifik ke MySQL Manual yang relevan dengan kasus yang sedang pusing-pusing-nya elo hadapin. Itu udah merupakan bantuan yang amat sangat bagus.

Gw lupa, apa wahyu pertama yg diterima Rasulullah dari Malaikat Jibril?
"RTFM!"

eh bukan...

"iqro!"

BACALAH...

361.gif
360.gif

selfe...@gmail.com

unread,
Feb 22, 2009, 5:05:35 AM2/22/09
to mysql-i...@googlegroups.com
Hello,
Sunday, February 22, 2009, 12:45:06 PM, you wrote:

Saya mohon maaf kalau bapak2 tersinggung, udah hampir 1 minggu obok2
nggak berhasil juga.

Saya punya
tblhdrjurnal no_dok C(9), tanggal D(), thnbln C(6)
tbldtljurnal no_dok C(9), no_acct C(10), t_db N(14,2), t_cr N(14,2),
thnbln C(6)
tblchat no_acct C(9), cd_group C(3), nama_chat C(40), tahun C(4),cr_01 N(14,2), db_01 N(14,2)
tblgroup cd_group C(3), nama_group C(45), db_01 N(14,2), cr_01
N(14,2)
dst.

saya mau setiap kali input data ke tbldtljurnal langsung trigger ke
tblchat sesuai bulannya.
dan trigger ke tblgroup juga.

Saya coba bikin trigger seperti yang bapak2 sarankan pakai var

SELECT a.tanggal, b.no_acct, b.t_db, b.t_cr INTO @tanggal, @no_acct, @t_db, @t_cr
FROM tblhdrjurnal AS a, tbldtljurnal AS b
WHERE a.no_dok = b.no_dok AND b.no_acct = NEW.no_acct;

waktu di jalankan di applikasi langsung error, result consisted of
more than one row.

Lalu saya coba hanya bikin select tblhdrjurnal.tanggal INTO @tgl
from tblhdrjurnal
hasil juga sama keluar error seperti diatas.


DELIMITER $$
DROP TRIGGER /*!50032 IF EXISTS */ `dblintas`.`tr_insert_jurnal`$$
CREATE
/*!50017 DEFINER = 'root'@'localhost' */

TRIGGER `dblintas`.`tr_insert_jurnal` AFTER INSERT ON `dblintas`.`tbldtljurnal`
FOR EACH ROW BEGIN

SELECT a.tanggal, b.no_acct, b.t_db, b.t_cr INTO @tanggal, @no_acct, @t_db, @t_cr
FROM tblhdrjurnal AS a, tbldtljurnal AS b
WHERE a.no_dok = b.no_dok AND b.no_acct = NEW.no_acct;

CASE
WHEN MONTH(@tanggal) = 1 AND NEW.t_cr > 0 THEN


UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;

WHEN MONTH(@tanggal) = 1 AND NEW.t_db > 0 THEN


UPDATE tblchat set cr_01 = NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;

WHEN MONTH(@tanggal) = 2 AND NEW.t_cr > 0 THEN


UPDATE tblchat set cr_01 = NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;

WHEN MONTH(@tanggal) = 2 AND NEW.t_db > 0 THEN


UPDATE tblchat set cr_01 = NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;

ELSE
$$
DELIMITER ;

selfe...@gmail.com

unread,
Feb 22, 2009, 6:31:18 AM2/22/09
to Rizky Prihanto
Hello Rizky,

Sunday, February 22, 2009, 12:45:06 PM, you wrote:

Saya sudah berhasil pak, update ke tblchatnya.
mau tanya lagi, bagusnya klu mau update ke tblgroup triggernya di sisi
tblchat atau di gabung di tbldtljurnal pak.

key yang dipakai adalah cd_group
tblgroup cd_group C(3), db_01, cr_01
tblchat no_acct C(10), cd_group C(3)


DELIMITER $$
DROP TRIGGER /*!50032 IF EXISTS */ `dblintas`.`tr_insert_jurnal`$$
CREATE
/*!50017 DEFINER = 'root'@'localhost' */

TRIGGER `dblintas`.`tr_insert_jurnal` AFTER INSERT ON `dblintas`.`tbldtljurnal`
FOR EACH ROW BEGIN

SELECT a.tanggal INTO @tanggal FROM tblhdrjurnal AS a
WHERE a.no_dok = NEW.no_dok LIMIT 1;
CASE
WHEN MONTH(@tanggal) = 1 AND NEW.t_db > 0 THEN
UPDATE tblchat set db_01 = db_01 + NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;
WHEN MONTH(@tanggal) = 2 AND NEW.t_db > 0 THEN
UPDATE tblchat set db_02 = db_02 + NEW.t_db WHERE tblchat.no_acct = NEW.no_acct;
/*Kredit*/
WHEN MONTH(@tanggal) = 1 AND NEW.t_cr > 0 THEN
UPDATE tblchat set cr_01 = cr_01 + NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;
WHEN MONTH(@tanggal) = 2 AND NEW.t_cr > 0 THEN
UPDATE tblchat set cr_02 = cr_02 + NEW.t_cr WHERE tblchat.no_acct = NEW.no_acct;


ELSE
BEGIN END;
END CASE;

END;
$$

DELIMITER ;

Rizky Prihanto

unread,
Feb 22, 2009, 6:48:13 AM2/22/09
to mysql-i...@googlegroups.com
klo dari yang Bapak ceritakan di email sebelumnya, sepertinya lebih bagus kalo proses manipulasi tabel tblgroup juga digabung di trigger pada tbldtljurnal. Bisa saja sih ditaroh di trigger tblchat AFTER UPDATE. tapi ini semua kembali ke desain trigger Anda.

Perlu diperhatikan, dalam penggunaan trigger bisa amat sangat berbahaya kalo trigger tersebut saling memicu event trigger pada tabel lain. Circular Trigger, dalam beberapa kesalahan desain dapat membuat MySQL memproses insert/update/delete tanpa henti ke beberapa tabel. Oleh karena itu, berhati-hatilah dalam mendesain trigger. Kalo perlu, didesain dulu dengan menggunakan flowchart untuk memastikan "skenario" insert/update/delete Anda yang melibatkan trigger tidak menyebabkan circular trigger.



Tapi, ada kalanya "permainan" Circular Trigger ini bisa menjadi sangat menarik. Anda bisa baca-baca hacking ke MySQL terhadap trigger di artikel ini jika berkenan.

Owya, alamat email mysql-i...@googlegroups.com ini bukan merupakan alamat email saya, tetapi melainkan alamat milis. Harap Bapak ganti address-book email bapak supaya email mysql-indonesia@googlegroups tidak Bapak kasih label nama saya. ^_^

Terima kasih, dan senang sekali Bapak bisa meramaikan milis ini dengan kasus-kasus yang "cukup berbobot".


NB :
maaf di email reply saya yang pertama saya memakai bahasa loe-loe-gue-gue... mohon maaf jika hal tsb dianggap kurang berkenan.


--
regards,

Rizky Prihanto
http://rizky.prihanto.web.id
Phone #1 : 0812 535 22 392
Phone #2 : 0856 496 00 496


2009/2/22 <selfe...@gmail.com>
32B.gif
1E3.gif
320.gif
Reply all
Reply to author
Forward
0 new messages