问题描述
我被困在某个地方,需要您的帮助.
I am stuck at somewhere and I need some help from you.
我有两个数据库,即test_db1
和test_db2
,并且在两个数据库上都有users
表.两个数据库最初都是空的(0行).
I have two databases i.e., test_db1
and test_db2
and have users
table on both of them. Both databases initially are empty (0 rows).
这是users
表模式:
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
之后,我在test_db1.users
表上为INSERT
,UPDATE
和DELETE
事件编写了一些触发器,以下是每个触发器的作用:
After that, I have written some triggers for INSERT
, UPDATE
and DELETE
events on test_db1.users
table, Below is what each trigger does:
- 在
test_db1.users
中的INSERT
上,在test_db2.users
中插入同一行在 - ,在
test_db2.users
中更新同一行 - 在
test_db1.users
中的DELETE
上,从test_db2.users
中删除同一行
test_db1.users
中UPDATE
上的- on
INSERT
intest_db1.users
, insert same row intest_db2.users
- on
UPDATE
intest_db1.users
, update same row intest_db2.users
- on
DELETE
intest_db1.users
, delete same row fromtest_db2.users
这是触发代码段.
DELIMITER //
-- TRIGGER FOR INSERT
DROP TRIGGER IF EXISTS `test_db1_users_bi`;
CREATE TRIGGER `test_db1_users_bi` BEFORE INSERT ON `users` FOR EACH ROW
BEGIN
INSERT INTO `test_db2`.`users` (id, name, age) VALUES (NEW.id, NEW.name, NEW.age);
END; //
-- TRIGGER FOR UPDATE
DROP TRIGGER IF EXISTS `test_db1_users_bu`;
CREATE TRIGGER `test_db1_users_bu` BEFORE UPDATE ON `users` FOR EACH ROW
BEGIN
UPDATE `test_db2`.`users`
SET name = NEW.name,
age = NEW.age
WHERE id = NEW.id;
END; //
-- TRIGGER FOR DELETE
DROP TRIGGER IF EXISTS `test_db1_users_bd`;
CREATE TRIGGER `test_db1_users_bd` BEFORE DELETE ON `users` FOR EACH ROW
BEGIN
DELETE FROM `test_db2`.`users`
WHERE id = OLD.id;
END; //
-- DELIMITER;
现在,问题!
当前,它在触发器中没有定义任何错误/异常处理程序..因此,我也想处理该错误/异常处理程序,但我不知道该怎么做.我只是不知道如何获取异常及其异常之类的属性-错误代码,错误消息?
Currently, this doesn't have any errors/exceptions handlers defined in triggers.. So, I want to handle that too but I don't know how to do that. I just don't know how would I get the exception and it's properties like exceptions - error code, error message?
我只想将捕获的异常/错误从每个触发器(如果失败)存储到test_db1
.errors
表中:
I just want to store the caught exception/error into test_db1
.errors
table from each of the trigger (if fails):
这是errors
表架构,如下所示:
Here's errors
table schema something looks like:
DROP TABLE IF EXISTS `errors`;
CREATE TABLE `errors` (
`id` int(11) AUTO_INCREMENT,
`error_code` varchar(30) DEFAULT NULL,
`error_message` TEXT DEFAULT NULL,
`emailed` TINYINT DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
仅供参考:以下是可能的失败:
FYI: Below are the possible failures:
- 如果
test_db2
不存在或无法连接? - 如果
INSERT
触发器失败,即是什么原因? - 如果
UPDATE
触发器失败,即是什么原因? - 如果
DELETE
触发器失败,即是什么原因?
- If
test_db2
is not there or unable to connect? - If
INSERT
trigger fails i.e., whatever the reason? - If
UPDATE
trigger fails i.e., whatever the reason? - If
DELETE
trigger fails i.e., whatever the reason?
如果有人可以,请让我知道如何获取异常及其错误代码,错误消息的属性,并将其存储到触发器内部的变量中,以便执行插入操作以将其存储到表中?
If anyone can Just let me know how can I get the exception and it's properties like error code, error message and store it to variables from inside triggers so that then I will perform insert to store them into table?
我正在运行MySQL版本:5.5 +
I am running MySQL version: 5.5+
谢谢!
推荐答案
我通过DECLARE CONTINUE HANDLER
和GET DIAGNOSTICS CONDITION
找到了一个黑客,所以我想,我必须在这里分享它.
I found a hack via DECLARE CONTINUE HANDLER
and GET DIAGNOSTICS CONDITION
, so just thought, I must share it here.
这是我完整的最终脚本,该脚本使两个数据库users
表保持备份(同步),这意味着test_db1
(我们可以将其称为productionDB)上的任何更新都将在test_db2
上进行(我们可以将其称为stagingDB):
Here's my complete final script which keeps backup (sync) for both databases users
table what it means is that any update on test_db1
(which we may call it as a productionDB) will occur on test_db2
(which we may call it to as stagingDB):
/*
Create two databases:
1. `test_db1`
2. `test_db2`
and execute below create *Table script* on both databases.
after that execute *Triggers Script* on `test_db1` only..
*/
/*
TABLE STRUCTURE FOR `users`
*/
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) AUTO_INCREMENT NOT NULL,
`name` varchar(30) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
/*
TABLE STRUCTURE FOR `errors`
*/
DROP TABLE IF EXISTS `errors`;
CREATE TABLE IF NOT EXISTS `errors` (
`id` int(11) AUTO_INCREMENT NOT NULL,
`code` varchar(30) NOT NULL,
`message` TEXT NOT NULL,
`query_type` varchar(50) NOT NULL,
`record_id` int(11) NOT NULL,
`on_db` varchar(50) NOT NULL,
`on_table` varchar(50) NOT NULL,
`emailed` TINYINT DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
/*
TRIGGERS SCRIPTS FOR INSERT, UPDATE AND DELETE OPERATIONS
*/
DELIMITER //
-- TRIGGER FOR INSERT
DROP TRIGGER IF EXISTS `test_db1_users_ai`;
CREATE TRIGGER `test_db1_users_ai` AFTER INSERT ON `users` FOR EACH ROW
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT DEFAULT '';
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
END;
-- Perform the insert
INSERT INTO `test_db2`.`users` (id, name, age) VALUES (NEW.id, NEW.name, NEW.age);
-- Check whether the insert was successful
IF errorCode != '00000' THEN
INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'insert', NEW.id, 'test_db2', 'users');
END IF;
END; //
-- TRIGGER FOR UPDATE
DROP TRIGGER IF EXISTS `test_db1_users_au`;
CREATE TRIGGER `test_db1_users_au` AFTER UPDATE ON `users` FOR EACH ROW
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT DEFAULT '';
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
END;
-- Perform the update
UPDATE `test_db2`.`users`
SET name = NEW.name,
age = NEW.age
WHERE id = NEW.id;
-- Check whether the update was successful
IF errorCode != '00000' THEN
INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'update', NEW.id, 'test_db2', 'users');
END IF;
END; //
-- TRIGGER FOR DELETE
DROP TRIGGER IF EXISTS `test_db1_users_ad`;
CREATE TRIGGER `test_db1_users_ad` AFTER DELETE ON `users` FOR EACH ROW
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT DEFAULT '';
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
END;
-- Perform the delete
DELETE FROM `test_db2`.`users`
WHERE id = OLD.id;
-- Check whether the insert was successful
IF errorCode != '00000' THEN
INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'delete', OLD.id, 'test_db2', 'users');
END IF;
END; //
-- DELIMITER;
希望这对其他人来这里有帮助.
Hope this will help others when they come over here.
干杯
这篇关于如何将MySQL触发器异常/失败信息存储到表或变量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!