首页 > 解决方案 > 如何创建一个 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_idgroup_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

我来到这里是因为我的努力在故障排除方面是徒劳的。希望听到一些反馈。谢谢!

标签: sqloracleplsqlcounttriggers

解决方案


您的代码的即时问题是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

推荐阅读