当列名是动态的时,如何从触发器更新表?

问题描述:

模式和数据测试数据库 - https://gist.github.com/koceg/435c0d2b1246a69d048f当列名是动态的时,如何从触发器更新表?

我的目标是当有人插入在objects_properties新行表更新表。要更新的列的名称是动态的 - 它取决于property_idobjects_properties

到目前为止,我已经创建了一个触发器和存储过程,但我得到这个错误:

Dynamic sql is not allowed in stored function or trigger.

难道我做错了什么,或者MySQL的不允许调用存储过程用一备触发器内的语句?如果是这样,我该怎么做我想要的?

我有一个主意,但即使在伪代码中也很难看。真正的SQL会更糟糕,因为会有几十个代码:

SWITCH (property_code) 
    CASE 'name' 
     INSERT INTO boards (id, name) VALUES (@object_id, @value) ON DUPLICATE KEY UPDATE name = @value; 

    CASE 'address' 
     INSERT INTO boards (id, address) VALUES (@object_id, @value) ON DUPLICATE KEY UPDATE address = @value; 

    CASE 'district' 
     INSERT INTO boards (id, district) VALUES (@object_id, @value) ON DUPLICATE KEY UPDATE district = @value; 

P.S.我无法将这个逻辑移动到我的应用程序中,因为这个数据库被多个应用程序使用。

+0

这是一个设计不好的架构,但我无能为力...... – 2014-12-19 09:08:20

+0

根据MySQL文档:[D.1限制存储的程序](http://dev.mysql.com/doc/refman /5.6/en/stored-program-restrictions.html):“SQL准备语句([PREPARE](http://dev.mysql.com/doc/refman/5.6/en/prepare.html),[EXECUTE]( http://dev.mysql.com/doc/refman/5.6/en/execute.html),[DEALLOCATE PREPARE](http://dev.mysql.com/doc/refman/5.6/en/deallocate-prepare。 html))可以用于存储过程,但不能用于存储函数或触发器,因此,存储函数和触发器不能使用动态SQL(将语句构造为字符串并执行它们)。 – wchiquito 2014-12-19 10:19:26

+0

一些选项:不要使用触发器来使用Prepared Statements,或使用触发器而不使用Prepared Statements。 – wchiquito 2014-12-19 10:25:44

的当前的MySQL(5.7)上存储程序手册D1部分的限制规定,

  1. SQL语句准备(准备,执行DEALLOCATE备)可以在存储过程中使用,但没有存储功能或触发。因此,存储的函数和触发器不能使用动态SQL(将语句构造为字符串,然后执行它们)。
  2. 通常,SQL预准备语句中不允许的语句在存储程序中也是不允许的。有关作为预备语句支持的语句列表。
  3. 由于局部变量仅在存储程序执行期间处于作用域中,因此在存储程序中创建的预处理语句中不允许对它们进行引用。编写的语句范围是当前会话,而不是存储的程序,因此语句可以在程序结束后执行,此时变量将不再处于范围内。 所以你可以看到它不被允许。

问候。