Mysql

MySQL:來自觸發器的儲存過程給出重複的結果

  • May 23, 2020

我創建了一個儲存過程來將數據插入到審計表中。該過程接受一個參數,該參數採用表名,並且與 PK 一起將相同的值插入到審計表中。

當我從 AFTER DELETE 觸發器呼叫此儲存過程時,它會從多個表中插入重複值。基本上,為審計表中的所有表名插入相同的 PK 值。因此,如果我從表中刪除一條記錄,則審計表中單個刪除的插入數 = 觸發器數。

CREATE PROCEDURE sp_ins_log(
trigger_name VARCHAR(64),
column_name VARCHAR(64),
column_value VARCHAR(255),
requested_by VARCHAR(100))
INSERT INTO log (request_id,reference_schema, reference_table, reference_field, reference_id, action_performed, requested_by)
SELECT 
(SELECT trx_id FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_mysql_thread_id = CONNECTION_ID()),
EVENT_OBJECT_SCHEMA, 
EVENT_OBJECT_TABLE, 
column_name,
column_value, 
CONCAT(ACTION_TIMING,'_',EVENT_MANIPULATION),
IFNULL(requested_by,CURRENT_USER()) 
FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME = trigger_name AND TRIGGER_SCHEMA = SCHEMA();
CREATE TRIGGER tr_table_ad
AFTER DELETE
ON table_name FOR EACH ROW
CALL sp_ins_log('table_name',old.id);

但是,如果我在每個觸發器中單獨放置相同的插入查詢,它就可以正常工作。

重現問題DB Fiddle

將此與在 SP 中直接執行 INSERT 查詢進行比較。

原因很簡單——不准確。變數名和列名干擾。你鍵入WHERE TRIGGER_NAME = trigger_name. TRIGGER_NAME和都trigger_name被視為輸入變數名,並且此條件始終為真。您有 2 個觸發器與其餘條件匹配TRIGGER_SCHEMA = SCHEMA(),因此查詢返回 2 行。

只需重命名輸入變數。或者添加表別名,讓伺服器區分列名和變數名:WHERE INFORMATION_SCHEMA.TRIGGERS.TRIGGER_NAME = trigger_name AND TRIGGER_SCHEMA = SCHEMA();.

引用自:https://dba.stackexchange.com/questions/267762