2017-04-03 7 views
0

挿入前に2列をトリガーで更新しようとしていますが、予期せぬ結果があります。私はいくつかのデータを挿入し、最後の2列は値とともに自動的に挿入されます、ここで私の最初の試みです。 enter image description hereMySQL - 関数を使用して列値を更新し、挿入前にトリガーする

参照してください。最後の2列はnullですが、トリガーを設定してその列を自動的に満たす関数を設定しています。ここでは正確に同じデータを持つ私の第二の試み

enter image description here

最後の2列は、データで満たされているが、最初の試みが失敗している理由を私は理解していませんか?

ここで私は

CREATE TRIGGER `set_total_harga` BEFORE INSERT ON `tbl_transaksi_detail` 
FOR EACH ROW BEGIN 
set NEW.total_harga = hitungTotalHargaPerItem(NEW.qty, NEW.harga_satuan); 
END 

トリガー

BEGIN 
    DECLARE 
    q, 
    id_toko INT; 
    SET 
    id_toko =(
    SELECT DISTINCT 
     `tbl_transaksi`.`id_toko` 
    FROM 
     `tbl_transaksi`, 
     `tbl_transaksi_detail` 
    WHERE 
     `tbl_transaksi`.`no_transaksi` = no_trans 
); IF unit = "PCS" THEN 
SET 
    q =(
    SELECT 
    `tbl_harga_jual`.`harga_pcs` 
    FROM 
    `tbl_harga_jual` 
    WHERE 
    `tbl_harga_jual`.`id_barang` = id_brg AND `tbl_harga_jual`.`id_toko` = id_toko 
); RETURN q; ELSEIF unit = "PAK" THEN 
SET 
    q =(
    SELECT 
    `tbl_harga_jual`.`harga_pak` 
    FROM 
    `tbl_harga_jual` 
    WHERE 
    `tbl_harga_jual`.`id_barang` = id_brg AND `tbl_harga_jual`.`id_toko` = id_toko 
); RETURN q; ELSEIF unit = "KARTON" THEN 
SET 
    q =(
    SELECT 
    `tbl_harga_jual`.`harga_karton` 
    FROM 
    `tbl_harga_jual` 
    WHERE 
    `tbl_harga_jual`.`id_barang` = id_brg AND `tbl_harga_jual`.`id_toko` = id_toko 
); RETURN q; 
END IF; RETURN q; 
END 

機能set_Harga_Unit

CREATE TRIGGER `set_harga_satuan` BEFORE INSERT ON `tbl_transaksi_detail` 
FOR EACH ROW BEGIN 
set NEW.harga_satuan = set_Harga_Unit(NEW.unit, NEW.id_barang, NEW.no_transaksi); 
END 

列harga_satuanのための機能hitungTotalHargaPerItem total_harga列に使用私のトリガー

BEGIN 
DECLARE hasil int; 
    set hasil = qty * harga_satuan; 
    RETURN hasil; 
END 
+0

この関数では:hitungTotalHargaPerItem set hasil = qty * harga_satuan; harga_satuanがnullの場合、結果はnullになると思います – Cherif

答えて

-1

tbl_transaksi_detailにおける最初の挿入iが空のテーブルにトリガーbefore insertを使用するため、値no_transaksiがヌルである場合、(tbl_transaksi_detail)iは@Shadow

SET 
    id_toko =(
    SELECT DISTINCT 
     `tbl_transaksi`.`id_toko` 
    FROM 
     `tbl_transaksi`, 
     `tbl_transaksi_detail`<<== I DON'T NEED THIS 
    WHERE 
     `tbl_transaksi`.`no_transaksi` = no_trans 
); IF unit = "PCS" THEN 

からの手がかりに基づいて、機能set_Harga_UnitでSELECTクエリを間違えているように見えますので、私は今、それが、おかげでみんなを作業クエリ

SET 
     id_toko =(
     SELECT DISTINCT 
      `tbl_transaksi`.`id_toko` 
     FROM 
      `tbl_transaksi` 
     WHERE 
      `tbl_transaksi`.`no_transaksi` = no_trans 
    ); IF unit = "PCS" THEN 

からtbl_transaksi_detailを削除します!

+0

この解決法は持続可能ではありません。レコードを削除したり、 'tbl_transaksi'テーブルにロールバックした瞬間に、カウントは不正な値を返します。また、同時に複数のユーザーがトランザクションの詳細を挿入しようとすると安全ではありません。同時に複数のユーザーがトランザクションの詳細を挿入していなくても、最大のIDを得るには 'max(id_toko)'がもっと効率的です。さらに、あなたのソリューションは私が提供したものに基づいています。だから、あなた自身の答えを受け入れることは、正しいことではなく、公正でもありません。 – Shadow

0

根本原因のSERMはid_toko変数の値を設定し、その選択されるように:選択して

SET 
    id_toko =(
    SELECT DISTINCT 
     `tbl_transaksi`.`id_toko` 
    FROM 
     `tbl_transaksi`, 
     `tbl_transaksi_detail` 
    WHERE 
     `tbl_transaksi`.`no_transaksi` = no_trans 
); 

を使用すると、内部の別のテーブルの上にtbl_transaksi_detail(問題のトリガーを持つテーブル)に参加します。しかし、第1の場合では、tbl_transaksi_detailはまだが空であり、(の前にトリガーが)であるため、id_toko変数はnullに設定されます。

この結果、qがnullになり、結果として計算がすべてNULLに設定されます。

2番目のケースでは、すでにレコードがtbl_transaksi_detailテーブルに挿入されているため、計算ではnull以外の値が返されます。しかし、1番目と2番目のレコードの詳細はまったく同じなので、正しい値が返されます。

とにかくid_tokoを計算する選択を理解できません。これがトランザクションIDの場合は、自動インクリメントでトランザクションレコードが作成されたばかりの場合はlast_insert_id()を、id_tokoの最大値を得るにはmax(id_toko)を使用することができます(これはマルチユーザーにとって安全ではありません)。

関連する問題