Mysql
MySQL:來自觸發器的儲存過程給出重複的結果
我創建了一個儲存過程來將數據插入到審計表中。該過程接受一個參數,該參數採用表名,並且與 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();
.