前言
如題,提供批次更新的一種解決方案,不一定最優,僅僅是一種解決問題的思路,廢話不多說下面具體看一下應用情境和詳細的解決步驟~
應用情境
如下圖所示,是一個資訊編輯頁面:
可以這是一個標準的批量修改的功能,當使用者點擊“修改”按鈕時候頁面的資料變為可編輯狀態,可以修改1個或多個資料項目,點擊儲存後資料同步更新到DB。不知道各位看到這種功能時的第一思路是什麼呢。下面就從資料表設計開始談談我的思路和方案。
資料表設計
觀察上圖不難發現基本編輯項都為一些系統參數項,所以這種介面適用於不經常變化的一些參數或資料的維護,而且操作也較為簡單。既然是參數類型的資料,為了通用起見,我們肯定要設計成縱表的形式,如下圖所示:
很簡單,唯一關注一下abbr_name(拼音簡寫)這個欄位,由於在介面上我們的資料不是以列表的形式展示的,而是固定的、提前安排好哪個位置放什麼樣的資料,所以我們就需要挨個去指定<input/>文字框的name屬性,這裡我們定義一條規則:name屬性和表中的abbr_name保持一致,這樣做有兩個關鍵的好處。
第一,我們決定用pg的自訂函數來處理這個批次更新,思路就是給函數傳一個字串數組作為參數,在函數內部進行loop,擷取數組的每一個元素進行分割,擷取到update語句需要的參數值。這個數組的每一個元素是“參數名+分隔字元+參數值”的一個字串,例如“nwdz#8.8.8.8”,我就是以井號作為分隔字元,前面串接參數名,後面串接參數值,這樣當這個字串傳入函數的時候,我再通過pg的字串函數進行分割,就直接得到了需要update set所需要的param_value和where條件中的所需要的abbr_name。
第二,方便顯示。我們的顯示介面明顯不是一個可用foreach標籤迴圈的List,而且當資料量較大時候如何顯示。一個一個查,很麻煩不可取,所以這時abbr_name和<input/>的name一致的好處就體現出來了:我們依然在後台查詢返回一個List,資料傳到頁面後轉換成json數組,通過js去遍曆的時候我們可以通過jquery的$(input[name='xxx']).val(xxx)來實現頁面資料的填充,有點js基礎的話應該可以想來是如何?的,再貼一小段參考代碼:
success:function(data){ var ulistJosn = getStrJson(data); for ( var i = 0; i < ulistJosn.length; i++) { var abbrname = ulistJosn[i].abbrname; var paramvalue = ulistJosn[i].paramvalue; $("input[name="+abbrname+"]").val(paramvalue); } }
最後來看一下批次更新的自訂函數:
CREATE OR REPLACE FUNCTION func_update_basic_param(arr text[]) RETURNS void AS $body$ declare arrLength integer; rownum integer := 0; elementStr text; elementPartOne text; elementPartTwo text; BEGIN arrLength = array_length(arr,1); -- begin loop while rownum < arrLength LOOP -- rebuild string elementStr:=arr[rownum]; elementPartOne:=split_part(elementStr,'%',1); elementPartTwo:=split_part(elementStr,'%',2); -- do update update t_sys_param_settings set param_value = elementPartTwo where abbr_name = elementPartOne; rownum := rownum + 1; END LOOP; RETURN; END; $body$ LANGUAGE 'plpgsql';
用到幾個簡單的pg內建函數,例如:array_length(anyarray,int) 返回數組指定維度長度,split_part(str,del,field)根據del分割str返回產生的第field個子字串。寫這個函數的目的也就是為了減少串連資料庫的次數,通過一次調用完成大量操作。
總結
本篇僅僅記錄了一種較為簡單的批次更新的實現方式,順便學習一下postgresql自訂函數的基本文法,整體和oracle的procedure還是很類似的,如果有錯誤的地方和更好的建議歡迎批評指正,The End。