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

时间:2014-12-19 09:02:58

标签: mysql sql

测试数据库的模式和数据 - https://gist.github.com/koceg/435c0d2b1246a69d048f

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

到目前为止,我已创建了触发器和存储过程,但我收到此错误:

  

存储函数或触发器中不允许使用动态sql。

我是做错了还是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。我无法将此逻辑移至我的应用程序,因为该数据库已被多个应用程序使用。

1 个答案:

答案 0 :(得分:2)

当前MySQL(5.7)手册部分D.1对存储程序的限制声明

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