MySQL触发更新动态列

时间:2017-02-25 12:32:17

标签: mysql triggers dynamic-columns

我有一个表,每次在另一个表中插入某些内容时我都需要更新。

要更新的表:counters上插入sales。 问题是将在counters中更新的列根据表sales中的插入而有所不同。

从昨天开始,我一直在寻找并寻找,但无济于事。 我尝试使用CAST(.. AS CHAR)功能,但无济于事。

这就是声明的样子:

CREATE TRIGGER `sales_AFTER_INSERT` AFTER INSERT ON `sales` FOR EACH ROW
BEGIN
    UPDATE counters SET {NEW.sale_provider} = {NEW.sale_provider} + NEW.sale_quantity WHERE counters.cnt_sendername = NEW.sale_sendername;
END;

其中{New.sale_provider}是要更新的列的名称。

计数器表看起来像:

| sendername | prov1 | prov2 | prov3 | ...

其中列名(prov1,prov2 ..)是提供者的ID

这可能吗?我怎样才能做到这一点? 我是触发器的新手,仍然缺乏对SQL语言和MySQL功能的深入理解。

注意:

  • 有4列作为开头,因为有4个提供者,计数器表可以快速访问限制而不是每次都计算它,这将被大量使用并且每次重新计算都非常耗费资源。 / LI>
  • 添加了每个新的提供者后,新的列将被添加到计数器表中,它也应该是可更新的,因此需要某种形式的变量。

非常感谢您的帮助!

编辑:

重点是更新的列每次都会有所不同,我知道这是非常规的,但我相信它是可行的。 插入sales的新数据会影响counter中的列,但会影响哪一列需要确定。

在寻找一段时间后,我找到了可以解决我需要的东西,但仍然无法让它运行:

CREATE TRIGGER `sales_AFTER_INSERT` AFTER INSERT ON `sales` FOR EACH ROW
BEGIN
    SET colname= New.sale_provider;
    UPDATE counters SET colname = colname + NEW.sale_quantity WHERE counters.cnt_sendername = NEW.sale_sendername;
END;

但它告诉我colname不是系统变量? 我一直在寻找如何分配变量,它们看起来像我做了什么,出了什么问题?

1 个答案:

答案 0 :(得分:0)

您可以使用每个列上的条件通过单个更新执行您想要的操作:

CREATE TRIGGER `sales_AFTER_INSERT` AFTER INSERT ON `sales` FOR EACH ROW
BEGIN
    UPDATE counters c
        SET prov1 = c.prov1  + (case when NEW.sale_provider = 'prov1' THEN NEW.sale_quantity else 0 end),
            prov2 = c.prov2  + (case when NEW.sale_provider = 'prov2' THEN NEW.sale_quantity else 0 end),
            prov3 = c.prov3  + (case when NEW.sale_provider = 'prov3' THEN NEW.sale_quantity else 0 end),
            prov4 = c.prov4 + (case when NEW.sale_provider = 'prov4' THEN NEW.sale_quantity else 0 end)         
        WHERE c.cnt_sendername = NEW.sale_sendername;
END;

我还建议您将表更改为每个提供程序一行。这样,您无需更改触发器即可添加新提供程序:

CREATE TRIGGER `sales_AFTER_INSERT` AFTER INSERT ON `sales` FOR EACH ROW
BEGIN
    UPDATE counters c
        SET quantity = c.quantity  + NEW.sale_quantity
        WHERE c.cnt_sendername = NEW.sale_sendername AND
              c.provider = NEW.sale_provider
END;

这使得将表格作为交叉表查询有点困难,但这不是什么大问题。

这两个都假设counters已预先初始化了所需的所有行。这可能不合理。因此,您应该在sales_after_insert(cnt_sendername, provider)上创建一个唯一索引并使用insert on duplicate key

CREATE TRIGGER `sales_AFTER_INSERT` AFTER INSERT ON `sales` FOR EACH ROW
BEGIN
    INSERT INTO counters(cnt_sendername, provider, quantity)
         VALUES (NEW.sale_sendername, NEW.sale_provider, NEW.sale_quantity)
         ON DUPLICATE KEY UPDATE quantity = quantity + VALUES(quantity);
END;