2014-12-19 51 views
5

模式和數據測試數據庫 - 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

回答

2

的當前的MySQL(5.7)上存儲程序手冊D1部分的限制規定,

  1. SQL語句準備(準備,執行DEALLOCATE備)可以在存儲過程中使用,但沒有存儲功能或觸發。因此,存儲的函數和觸發器不能使用動態SQL(將語句構造爲字符串,然後執行它們)。
  2. 通常,SQL預準備語句中不允許的語句在存儲程序中也是不允許的。有關作爲預備語句支持的語句列表。
  3. 由於局部變量僅在存儲程序執行期間處於作用域中,因此在存儲程序中創建的預處理語句中不允許對它們進行引用。編寫的語句範圍是當前會話,而不是存儲的程序,因此語句可以在程序結束後執行,此時變量將不再處於範圍內。 所以你可以看到它不被允許。

問候。

相關問題