【问题标题】:Oracle SQL trigger using add columns,comment使用添加列、注释的 Oracle SQL 触发器
【发布时间】:2021-11-24 03:51:50
【问题描述】:

我应该在 Oracle SQL 中创建一个触发器

  1. department_amount 列添加到位置表
  2. 添加注释“包含该位置的部门数量”
  3. 创建一个触发器,每次从部门插入/删除一行时,它将更新所在位置的部门数量。

表格:

CREATE TABLE departments
(
    department_id   NUMBER(4) PRIMARY KEY,
    department_name VARCHAR2(30) NOT NULL,
    manager_id      NUMBER(6),
    location_id     NUMBER(4)    NOT NULL
);

CREATE TABLE locations
(
    location_id    NUMBER(4) PRIMARY KEY,
    street_address VARCHAR2(40),
    postal_code    VARCHAR2(12),
    city           VARCHAR2(30),
    state_province VARCHAR2(25),
    country_id     CHAR(2) NOT NULL
);

【问题讨论】:

  • trigger 中完成所有这些操作似乎是一个非常糟糕的主意 - 为什么要在 inside中执行此操作> 触发器?似乎完全错误的地方......你的结构中的修改不应该被放入触发器(它们可能会一遍又一遍地执行,而没有你的控制!)
  • 这是一个 sql 培训,但我有点卡在触发器部分这就是我做这个问题的原因。它不是为了工作或只是为了教育目的
  • 嗯,要点是:不要在触发器中进行结构修改!从来没有。

标签: sql oracle triggers


【解决方案1】:

我认为这项任务非常不要那样做,没有任何意义。甚至不用于训练。

你需要做的是

  1. 检查locations.department_amount列是否存在。您可以通过查看系统视图 dba_tables(或 all_tablesuser_tables,如果适用)来执行此操作。
  2. 如果该列不存在,请通过ALTER TABLE 创建它。但是,这是 DDL,而不是 DML,因此您必须通过 EXECUTE IMMEDIATE 动态运行它。
  3. 如果您刚刚创建了列,请同时创建评论。
  4. 现在,在同一个触发器中,从department_amount 中加或减 1。因此,您可以保证第一个操作(导致创建列的操作)已经对其进行了更新。

第 1 点到第 3 点只需要发生在语句级别,而第 4 点应该发生在行级别。因此,为了避免其他触发器出现问题,这个触发器应该是复合触发器。

但是,如果可以在数据库中创建触发器,为什么不能也添加列及其注释呢?为什么必须编写触发器,以便它必须检查列是否存在?如前所述,这毫无意义,所以最好不要这样做。

【讨论】:

    【解决方案2】:

    回答你的问题

    将 department_amount 列添加到位置表

    alter table locations add department_amount number ; 
    

    添加评论“包含该地点的部门数量”

    comment on column locations.deparment_amount is 'Contains the amount of departments in the location';
    

    创建一个触发器,每次从部门插入/删除一行时,它将更新所在位置的部门数量。

    create or replace trigger trg_loc 
    after insert or delete on departments 
    declare
    begin
        merge into locations t 
        using ( select count(department_id) as dpt_amount, location_id as loc_id 
                from departments b 
                group by location_id ) s
        on (t.location_id = s.loc_id) 
        when matched then 
         update set t.department_amount = s.dpt_amount ;
    end;
    /
    

    下面有一个 dbfiddle 数据示例和触发器演示,当您为每个位置插入或删除部门时,该触发器演示会更新 locations 表中的 department_amount

    db<>fiddle

    【讨论】:

    • 谢谢老兄,但是我如何将添加部门金额和添加评论与触发器结合起来?我可以在一个触发器中以某种方式完成所有这些事情
    • 你不能。您将需要通过使用 dbms_scheduler 运行异步会话来欺骗数据库以克服该部分。我相信你的问题不是为了让你这样做。这些 DDL 命令旨在在外部执行,然后创建触发器来处理部门金额的更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 2014-06-28
    • 1970-01-01
    • 2015-03-26
    相关资源
    最近更新 更多