我想知道是否有人知道触发器在其中使用的视图发生更改后将 0 插入列的原因是什么。情况是这样的:
表 A 有 AFTER INSERT 触发器 => 触发器设置为运行视图,然后将结果插入表 B。
到目前为止,这一切都完美无缺。最近我不得不对触发器使用的视图做一个小改动。所做的更改是其中一列返回平均值而不是总和。手动运行视图会在更改的列中返回正确的数据。然而,触发器总是会从更改的列中返回 0。
我设法通过添加空白和保存来修复触发器,但这并不理想。我是不是遗漏了什么或者这是 MySQL 上的正常行为?
触发器
CREATE DEFINER=`root`@`%` TRIGGER trigger_A
AFTER INSERT
ON table_A FOR EACH ROW
BEGIN
select
date_time
, lines_
INTO
@date_time
, @lines_
from view_A where date_time = concat(substr(sysdate(),1,13),':00:00');
select count(*) into @hourly_check from able_B where date_time = concat(substr(sysdate(),1,13),':00:00');
if ( @hourly_check = 0 ) then
insert into table_B (date_time, lines_)
values (concat(substr(sysdate(),1,13),':00:00'), '0');
end if;
UPDATE `DATABASE`.`table_B`
SET
`lines_` = @lines_,
WHERE `date_time` = @date_time;
END
查看
CREATE
ALGORITHM = UNDEFINED
DEFINER = `root`@`localhost`
SQL SECURITY DEFINER
VIEW `view_A` AS
SELECT
CONCAT(SUBSTR(`table_A`.`date_time`, 1, 13),
':00:00') AS `concat(substr(date_time,1,13),':00:00')` as date_time,
ROUND(AVG(`table_A`.`lines_`), 1) AS `round(avg(lines_),1)` as lines_ -- this is where I changed from sum() to avg()
FROM
`table_A`
GROUP BY CONCAT(SUBSTR(`table_A`.`date_time`, 1, 13),
':00:00');
表_A
CREATE TABLE `table_A` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_time` timestamp NOT NULL DEFAULT current_timestamp(),
`lines_` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_date_time` (`date_time`)
);
源数据
日期_时间 | 行_ |
---|---|
2023-05-17 09:02:00 | 7 |
2023-05-17 09:04:00 | 18 |
表_B
CREATE TABLE `table_B` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_time` timestamp NOT NULL DEFAULT current_timestamp(),
`lines_` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_date_time` (`date_time`)
);
预期从触发器插入
日期_时间 | 行_ |
---|---|
2023-05-17 09:00:00 | 12.5 |
视图更改后插入
日期_时间 | 行_ |
---|---|
2023-05-17 09:00:00 | 0 |
谢谢
更新
这里是重现问题的设置
CREATE TABLE `table_A` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_time` timestamp NOT NULL DEFAULT current_timestamp(),
`lines_` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_date_time` (`date_time`)
);
CREATE TABLE `table_B` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_time` timestamp NOT NULL DEFAULT current_timestamp(),
`lines_` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_date_time` (`date_time`)
);
create unique index IX_date_time on table_B (date_time);
CREATE
VIEW `view_A` AS
SELECT
CONCAT(SUBSTR(`table_A`.`date_time`, 1, 13),
':00:00') as date_time,
ROUND(SUM(`table_A`.`lines_`), 1) as lines_
FROM
`table_A`
GROUP BY CONCAT(SUBSTR(`table_A`.`date_time`, 1, 13),
':00:00');
delimiter //
CREATE TRIGGER trigger_A
AFTER INSERT
ON table_A FOR EACH ROW
BEGIN
select
date_time
, lines_
INTO
@date_time
, @lines_
from view_A where date_time like '2023-05-19 09%';
insert into table_B (date_time, lines_)
values (@date_time, @lines_)
on duplicate key update date_time = @date_time
, lines_ = @lines_;
END;
//
delimiter ;
insert into table_A (id,date_time,lines_) values
('11', '2023-05-19 09:02:00', '7'),
('12', '2023-05-19 09:04:00', '18'),
('13', '2023-05-19 09:06:00', '7'),
('14', '2023-05-19 09:08:00', '18'),
('15', '2023-05-19 09:10:00', '9'),
('16', '2023-05-19 09:12:00', '25'),
('17', '2023-05-19 09:14:00', '15'),
('18', '2023-05-19 09:16:00', '50'),
('19', '2023-05-19 09:18:00', '49'),
('20', '2023-05-19 09:20:00', '50'),
('21', '2023-05-19 09:22:00', '2'),
('22', '2023-05-19 09:24:00', '5'),
('23', '2023-05-19 09:26:00', '2'),
('24', '2023-05-19 09:28:00', '5'),
('25', '2023-05-19 09:30:00', '2'),
('26', '2023-05-19 09:32:00', '5'),
('27', '2023-05-19 09:30:00', '2'),
('28', '2023-05-19 09:32:00', '5');
步骤是这样的:
id | 日期_时间 | 行_ |
---|---|---|
52 | 2023-05-19 09:00:00 | 276 |
table_A
.lines_
), 1) as lines_ => ROUND(AVG(table_A
.lines_
), 1) 作为行_结果
id | 日期_时间 | 行_ |
---|---|---|
52 | 2023-05-19 09:00:00 | 276 |
期待
id | 日期_时间 | 行_ |
---|---|---|
52 | 2023-05-19 09:00:00 | 15.3 |
这就是我的问题,改变视图不会反映在触发器中。它仍然会使用“旧”视图而不是更新后的视图
我在 Fedora 28 上使用 v10.2.15 MariaDB。
我测试了你的触发器,我创建了一个可以在here
中找到的测试环境触发器工作正常,我只删除了以下条件并且触发器按预期工作。
WHERE `date_time` = @date_time;
我也删除了
where date_time = concat(substr(sysdate(),1,13),':00:00');
条件以匹配您给定的数据。
给出以下数据示例,
CREATE TABLE `table_A` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_time` timestamp NOT NULL DEFAULT current_timestamp(),
`lines_` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_date_time` (`date_time`)
);
CREATE TABLE `table_B` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_time` timestamp NOT NULL DEFAULT current_timestamp(),
`lines_` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_date_time` (`date_time`)
);
CREATE
VIEW `view_A` AS
SELECT
CONCAT(SUBSTR(`table_A`.`date_time`, 1, 13),
':00:00') as date_time,
ROUND(AVG(`table_A`.`lines_`), 1) as lines_
FROM
`table_A`
GROUP BY CONCAT(SUBSTR(`table_A`.`date_time`, 1, 13),
':00:00');
触发器,
CREATE TRIGGER trigger_A
AFTER INSERT
ON table_A FOR EACH ROW
BEGIN
select
date_time ,
lines_
INTO
@date_time,
@lines_
from view_A ;
select count(*) into @hourly_check from table_B where date_time = concat(substr(sysdate(),1,13),':00:00');
if ( @hourly_check = 0 ) then
insert into table_B (date_time, lines_)
values (concat(substr(sysdate(),1,13),':00:00'), '0');
end if;
UPDATE table_B
SET
lines_ = @lines_ ;
END
一些插入数据,
insert into table_A (date_time,lines_) values
('2023-05-17 09:02:00','7'),
('2023-05-17 09:04:00','18');
最终结果
select *
from table_B;
id date_time lines_
1 2023-05-18 08:00:00 12.5