简体   繁体   English

MySQL触发器更新动态列

[英]MySQL trigger update dynamic column

I have a table that i need to update every time something is inserted in another table. 我有一个表,每次在另一个表中插入内容时都需要更新。

table to be updated: counters on insert in sales . 要更新的表:在sales插入的counters the problem is the column that will be updated in counters differs based on the insert in the table sales . 问题是,将在counters更新的列因表sales的插入而sales

I have been looking around and searching since yesterday, but to no avail. 从昨天开始,我一直在四处搜寻,但无济于事。 i tried using the CAST(.. AS CHAR) function but to no avail. 我尝试使用CAST(.. AS CHAR)函数,但无济于事。

this is what the statement should look like: 语句应如下所示:

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;

where the {New.sale_provider} is the name of the column to be updated. 其中{New.sale_provider}是要更新的列的名称。

counter table looks like: 计数器表如下:

| | sendername | 发件人姓名 | prov1 | prov1 | prov2 | prov2 | prov3 | prov3 | ... ...

Where column names (prov1,prov2..) are the id of the providers 其中列名(prov1,prov2 ..)是提供者的ID

Is this possible? 这可能吗? how can I do this? 我怎样才能做到这一点? I am new to triggers and still lack the deeper understanding of SQL language and MySQL's capabilities. 我是新手,但仍然对SQL语言和MySQL功能缺乏更深入的了解。

Notes: 笔记:

  • There are 4 columns as a start since there are 4 providers, the counter table serves a quick access to limits instead of calculating it every time, this will be used quite a lot and recalculating it every time is very resources consuming. 首先有4列,因为有4个提供者,计数器表提供了对限制的快速访问,而不必每次都进行计算,这将被大量使用,并且每次都要重新计算它非常消耗资源。
  • With every new provider added a new column will be added to the counter table, it should be updateable as well, thus some form of a variable is needed. 随着每个新提供程序的添加,新列将添加到计数器表中,该列也应该是可更新的,因此需要某种形式的变量。

your help is most appreciated! 非常感谢您的帮助!

EDIT: 编辑:

The point is that the updated column will be different every time, I know this is unconventional but i believe it is doable non the less. 关键是每次更新后的列都会有所不同,我知道这是非常规的,但我相信它是可行的。 The new data inserted into sales will affect a column in counter , but which column it will effect is what needs to be determined. 插入到sales的新数据将影响counter一列,但影响的列是需要确定的列。

After looking for a while i found something which can solve what i need, but still can't get it to run: 寻找了一段时间后,我发现可以解决我需要的东西,但仍然无法运行:

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;

but it tells me that colname is not a system variable? 但这告诉我colname不是系统变量吗? I have been searching for how to assign a variable and they all look like what i did, what is wrong? 我一直在寻找如何分配变量,它们都看起来像我所做的一样,这是什么问题呢?

You can do what you want with a single update, using a condition on each column: 您可以使用每列上的条件,通过一次更新即可完成您想要的操作:

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;

I would also recommend that you change the table to have one row per provider. 我还建议您将表更改为每个提供程序具有一行。 That way, you don't have to change the trigger to add new providers: 这样,您无需更改触发器即可添加新的提供程序:

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;

This makes querying the table as a cross-tab a little bit harder, but that is not a big deal. 这使得作为交叉表查询表变得有点困难,但这并不是什么大问题。

Both of these assume that counters is pre-initialized with all the rows it needs. 这两个都假定counters已使用其所需的所有行进行了预初始化。 This is probably not reasonable. 这可能是不合理的。 So, you should create a unique index on sales_after_insert(cnt_sendername, provider) and use insert on duplicate key : 因此,您应该在sales_after_insert(cnt_sendername, provider)上创建一个唯一索引, sales_after_insert(cnt_sendername, provider) insert on duplicate key使用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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM