【问题标题】:How can I increase the value of an attribute of one table on the basis of the insertion of value to an attribute of another table?如何在向另一个表的属性插入值的基础上增加一个表的属性值?
【发布时间】:2018-11-28 11:04:26
【问题描述】:

我有两张桌子。

CREATE TABLE `departments` (
department_id INT(2) NOT NULL AUTO_INCREMENT,
department_name VARCHAR(30) NOT NULL,
total_employees INT(4),
PRIMARY KEY (department_id),
UNIQUE (department_name));

CREATE TABLE `employees` (
employee_id INT(4) NOT NULL AUTO_INCREMENT,
employee_email VARCHAR(30) NOT NULL,
employee_first_name VARCHAR(30) NOT NULL,
employee_last_name VARCHAR(30) NOT NULL,
department_name VARCHAR(30) NOT NULL,
PRIMARY KEY (employee_id),
UNIQUE (employee_email),
FOREIGN KEY (department_name)
    REFERENCES departments (department_name)
    ON DELETE CASCADE);

现在,假设我有一个部门是人力资源管理。 2名员工有人力资源管理部门。因此,我希望通过触发器获取部门表 2 的 total_employees 的值。如果我能得到你的一些建议,那就太好了。

【问题讨论】:

  • 您实际上并不需要在字段中存储员工总数。您可以在您想知道它的时候使用查询中的 COUNT 来计算它。这是一种冗余的信息。如果您确实出于某种原因确实想存储它,那么是的,您可以编写一个触发器。但是......到目前为止,您尝试过做什么?你有什么问题?这不是免费的 write-my-code 或 do-my-research 服务。您可以轻松找到此类触发器的示例。这里不需要我们再提供教程了。
  • 看,我不指望你解决我的问题,我礼貌地请教一些建议。
  • 好的,谢谢。但从你之前写问题的方式来看,这并不清楚。我们无法读懂你的想法。无论如何,请使用“编辑”按钮将该代码和错误信息添加到问题本身中...... cmets 中的代码很难阅读,人们可能不会注意到它。评论仅用于要求澄清/提出简短建议,而不是添加对问题本身至关重要的内容。谢谢。
  • 如果你不建议,请忽略,我想有人愿意建议。
  • 在插入触发器中没有“旧”...因为您正在插入一行,而不是更新一行。该行没有以前的版本,因为它以前从未存在过。您可以使用new 在新创建的行中使用department_id。见stackoverflow.com/questions/25453535/…

标签: mysql sql rdbms database-trigger


【解决方案1】:

您似乎想要一个 update 触发器,而不是 insert 触发器。 insert 触发器是:

delimiter $$ 

create trigger employee_insertion_in_individual_department
after insert on employees for each row
begin
    update departments set 
        total_employees = total_employees + 1 
        where department_id = new.department_id;
    end if;
end$$

delimiter ;

update 触发器更像:

delimiter $$ 
create trigger employee_insertion_in_individual_department
after insert on employees for each row
begin
    if not (old.employee_department <=> old.employee_department) then
        update departments set 
            total_employees = total_employees + (case when department_id = old_department_id then -1 else 1 end)
            where department_id in (old.department_id, new.department_id);
    end if;
end$$

delimiter ;

【讨论】:

    【解决方案2】:

    在插入触发器中没有“旧”...因为您插入的是一行,而不是更新一行。该行没有以前的版本,因为它以前从未存在过。您可以使用new 来代替新创建的行中的department_id。而且你不需要if,因为没有什么可比的:

    delimiter $$ 
    create trigger employee_insertion_in_individual_department
      after insert on employees for each row begin
    
        update departments set total_employees=total_employees+1 
        where department_id=new.department_id; 
    
    end$$ delimiter ;
    

    另见How to get inserted value for trigger

    附:通过使用实际行的计数而不是简单的增量来更新它可能更安全。我担心如果几乎同时更改很多行,它可能会歪斜。可能值得测试这是否会导致问题。

    P.P.S.我假设您还计划出于相同目的添加 UPDATE 和 DELETE 触发器,如果​​您还没有这样做的话。

    【讨论】:

    • 我面临的一个问题,如果你能提供一些想法会很棒。
    • @Bappi_SB 你指的是什么问题?如果您有新问题,请提出一个新问题。如果您希望我查看,请将问题链接粘贴到这些 cmets 中。谢谢。
    • 我已经添加到这里了。如果您能对此发表看法,那就太好了。
    • 关于这个问题。已编辑。
    • 一旦现有问题得到解答,您就无法真正向现有问题添加新问题。否则从理论上讲,我们可以一直不断地处理新问题,这将不再是同一个问题,而且它实际上变成了多个问题(而不是一个),并且有被关闭过于宽泛的风险。对于提问者和回答者,它永远不会吸引更多的选票等。就像我说的,如果您有新问题,请提出新问题(如果仍然相关,您当然可以复制/粘贴此问题中的很多内容)。与此同时,你应该把它恢复到原来的样子。谢谢。
    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    相关资源
    最近更新 更多