sql - 如何创建一个 sql 触发器以在插入后将表列设置为等于一个值?
问题描述
oracle 和 sql 的新手,但正在尝试学习触发器。我想我在这里有一些语法错误,但让我解释一下我想要做什么。
我有两个表: 1. group_membership与列
user_internal_id | group_internal_id (FK) | joined_time
和 2. group_details与列
group_internal_id (PK) | group_name | group_owner | created_time | movie_cnt | member_cnt|
(PK 和 FK 分别代表与该主键相关的主键和外键。)
我想做的事:
将新行插入group_membership表后,我想用特定group_internal_id在group_membership表中出现的次数更新 group_details 表中member_cnt的值。
--
现在,我正在开发的应用程序的 DBA 创建了一个触发器,它通过读取插入到group_membership的行的group_internal_id来简单地更新特定组的member_cnt,然后将 member_cnt 加 1。哪个可能效果更好,但我想弄清楚我的触发器是如何出错的。这是下面的代码
CREATE OR REPLACE TRIGGER set_group_size
AFTER INSERT ON group_membership
FOR EACH ROW
DECLARE g_count NUMBER;
BEGIN
SELECT COUNT(group_internal_id)
INTO g_count
FROM group_membership
GROUP BY group_internal_id;
UPDATE group_details
SET member_cnt = g_count
WHERE group_details.group_internal_id = group_membership.group_internal_id;
END;
我收到的错误是:
Error(7,5): PL/SQL: SQL Statement ignored
Error(9,45): PL/SQL: ORA-00904: "GROUP_MEMBERSHIP"."GROUP_INTERNAL_ID": invalid identifier
我来到这里是因为我的努力在故障排除方面是徒劳的。希望听到一些反馈。谢谢!
解决方案
您的代码的即时问题是update
您的触发器的查询:
UPDATE group_details
SET member_cnt = g_count
WHERE group_details.group_internal_id = group_membership.group_internal_id;
group_membership
未在该范围内定义。要引用正在插入的行上的值,请改用伪表:new
。
WHERE group_details.group_internal_id = :new.group_internal_id;
另一个问题是select
查询,它可能返回多行。它需要一个where
过滤新插入的子句group_internal_id
:
SELECT COUNT(*)
INTO g_count
FROM group_membership
WHERE group_internal_id = :new.group_internal_id;
但这些明显的修复是不够的。Oracle 不会让您select
离开触发器触发的表。在执行时,您会遇到错误:
ORA-04091: table GROUP_MEMBERSHIP is mutating, trigger/function may not see it
没有简单的方法可以解决这个问题。让我建议整个设计都被破坏了;每个组的成员数是派生信息,可以在需要时轻松即时计算。例如,您可以使用视图,而不是尝试存储它:
create view view_group_details as
select group_internal_id, group_name,
(
select count(*)
from group_membership gm
where gm.group_internal_id = gd.group_internal_id
) member_cnt
from group_details gd
推荐阅读
- javascript - 在 Crafty.js 中以实体为中心?
- node.js - .catch((err) => { 在第一个括号处出错
- javascript - 以前可以通过 Javascript 访问 HTTP 请求
- x86 - CPU 如何“准确地”读取和执行 bios 代码?
- sql - 使用默认值填充雪花表而不从文件数据中选择默认列值
- python - Python中的求和值
- python - 检查字符串以在 spark 数据框中创建新列
- python - inverseTransform 是否应该是模型进行预测的静态方法
- c# - 如何使用 c# 将 1606813200000 转换为 2020-12-01T09:00:00.000Z
- mysql - 我如何在 sql 中将我的 id null 修改为 not null