MySQL - 在插入前用函数和触发器更新列值

问题描述:

我想在插入前用触发器更新2列,但我有意想不到的结果。我插入一些数据,最后2列将自动插入值,这里我的第一次尝试 enter image description hereMySQL - 在插入前用函数和触发器更新列值

请参阅?最后2列是空的,即使我设置了一些触发器和函数来自动填充这些列。在这里我恰有相同的数据

第二次尝试

enter image description here

最后2中填入数据,但我不明白为什么第一次尝试失败了呢?

这里我触发我在列中使用total_harga

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 

触发列harga_satuan

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 

功能set_Harga_Unit

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 

功能hitungTotalHargaPerItem

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

在这个函数中:hitungTotalHargaPerItem set hasil = qty * harga_satuan;如果harga_satuan为空,我认为结果将为空 – Cherif

它似乎我已经在功能set_Harga_Unit误选择查询的基础上,从线索@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 

tbl_transaksi_detail第一插件,该值no_transaksi为null,因为我在空表使用触发器before inserttbl_transaksi_detail) ,所以我删除tbl_transaksi_detail查询

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

现在它工作,谢谢大家!

+0

此解决方案不可持续。在你删除一条记录的时候,或者只是在'tbl_transaksi'表中有一个回滚,那么计数将返回一个不正确的值。另外,如果您有多个用户试图同时插入交易详情,这并不安全。即使您没有多个用户同时插入事务详细信息,“max(id_toko)”也会更有效地获得最高的事务id。此外,您的解决方案基于我提供的解决方案。所以,接受你自己的答案既不正确也不公平。 – Shadow

根本原因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(与有关触发器的表)。但是在第一种情况下tbl_transaksi_detail仍然是空的(触发器是之前插入),因此id_toko变量设置为空。

这将导致q为空,从而导致整个计算设置为空。

在第二种情况下,已经有一条记录插入到tbl_transaksi_detail表中,因此计算返回一个非空值。但它仅返回正确的值,因为第1条和第2条记录的详细信息完全相同。

我真的不明白,无论如何选择计算id_toko。如果这是一个交易ID,那么如果它是自动增量并且刚刚创建了交易记录,则可以使用last_insert_id(),或者使用max(id_toko)以获得最高值id_toko(这不是多用户安全的)。