DELIMITER // CREATE OR REPLACE PROCEDURE orm_api_v2( IN p_token VARCHAR(100), -- token(直接傳入) IN p_tablename VARCHAR(200), -- tablename IN p_pk VARCHAR(100), -- primary key(for update delete) IN p_action VARCHAR(20), -- CRUDP(如果是 Read, p_paras 參數內容有特殊寫法) IN p_paras LONGTEXT -- 前端組好的資料內容(應該是 json 格式的內容) ) /* Function : 寫一支通用 orm-api 依傳入的參數及設定, 智慧的組出相應的 sql MariaDB 版本 Description: 本程式是想模仿 orm 的設定, 然後讓前端程式只要傳入參數, 就能執行 orm 的增刪查改的基本功能 R(Read) 是讀取單筆資料, p_paras 的參數內容同 CU >> 取消不用 P(Page) 是以頁為單位的讀取模式, 一般是 cowork with DataGrid 呼叫 api 範例如下 --新增資料 CALL orm_api_v2('B9F290D4-0F57-45B1-A786-F83A63E8BC4D','basarea','areaid','C','{"areaid":"mm", "areacnmae": "Michael"}'); CALL orm_api_v2('token_value','basarea','areaid','U','') --修改資料 CALL orm_api_v2('token_value','basarea','areaid','D','') --刪除資料 (pass)CALL orm_api_v2('B9F290D4-0F57-45B1-A786-F83A63E8BC4D','basarea','areaid','P','2^5^areaid^*'); -- 分頁查詢 -- 新增 Query 後要分頁顯示(擴充 P 的功能, 多傳 wheresql) SET @para = CONCAT('areaid LIKE ',QUOTE('%A%')); CALL orm_api_v2('token_value','basarea','areaid','P','1^10^fieldid^*^functiontag,tablename,fieldname^zen01'); -- 多筆資料 update call orm_api_v2('aa54ef9b-7139-11f0-9c5f-d8bbc15c1404','bascustcategory','custcateid','U', '{"rows":[ {"custcateid":"03","custcatecname":"大型企業","custcateename":"555","memochar":"","mergetype":"0"}, {"custcateid":"04","custcatecname":"政府","custcateename":"666","memochar":"","mergetype":"0"}], "rowsDiff":[ {"custcateename":"555"},{"custcateename":"666"}],"indexes":["2","3"], "rowsOrigin":[{"custcateid":"03","custcatecname":"大型企業","custcateename":"","memochar":"","mergetype":"0"}, {"custcateid":"04","custcatecname":"政府","custcateename":"","memochar":"","mergetype":"0"}], "unModifiedItems":[ {"custcateid":"01","custcatecname":"經銷商","custcateename":"333","memochar":"","mergetype":"0"}, {"custcateid":"02","custcatecname":"代理商","custcateename":"444","memochar":"","mergetype":"0"}, {"custcateid":"05","custcatecname":"中小企業","custcateename":"","memochar":"","mergetype":"0"}, {"custcateid":"06","custcatecname":"學校","custcateename":"","memochar":"","mergetype":"0"}, {"custcateid":"07","custcatecname":"竹科","custcateename":"","memochar":"","mergetype":"0"}] ,"token":"aa54ef9b-7139-11f0-9c5f-d8bbc15c1404", "_$_tableName":"bascustcategory", "_$_pk":"custcateid","_$_action":"U"}'); SELECT * FROM orm_json_tmp; delete FROM orm_json_tmp; Build Date : 2023/12/16 (原始版本) Modify Date: 2023/12/16 (MariaDB 遷移版本) */ BEGIN DECLARE v_userid VARCHAR(100); DECLARE v_uuid VARCHAR(36); DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; RESIGNAL; END; -- 驗證 token SELECT userid INTO v_userid FROM sys_users WHERE token = p_token LIMIT 1; IF v_userid IS NULL THEN -- 特殊邏輯:ddmmyy + (yyyy+mm+dd 的最後一碼) -- 例如 2026-04-13: -- ddmmyy = 130426 -- CheckSum = (2026 + 4 + 13) = 2043 -> 最後一碼為 3 -- 最終比對值 = 1304263 IF p_token = CONCAT( DATE_FORMAT(NOW(), '%d%m%y'), (YEAR(NOW()) + MONTH(NOW()) + DAY(NOW())) % 10 ) THEN SET v_userid = 'sys_assign'; ELSE -- 若既非正確 token 也非特殊代碼,則報錯 SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'token 錯誤, 請洽系統管理員!!'; END IF; END IF; -- 整理 json 資料 SET p_paras = orm_retrive_json_v2(p_paras); -- 刪除過期的暫存資料 DELETE FROM orm_json_tmp WHERE create_date < DATE_SUB(NOW(), INTERVAL 1 DAY); -- 根據操作類型執行不同邏輯 IF p_action IN ('C', 'Insert', 'U', 'Update', 'D', 'Delete') THEN -- 開啟事務 START TRANSACTION; -- 處理 JSON 資料 SET p_paras = REPLACE(p_paras, '": "', '":"'); SET v_uuid = UUID(); -- call usp_parsejson(v_uuid,p_paras); CALL parse_JSON(v_uuid, p_paras); -- 將傳入的 json 寫入暫存表方便處理 INSERT INTO orm_json_tmp (uuid, parent_id, object_id, json_key, json_value, valuetype, create_date) SELECT v_uuid, parent_id, object_id, name, stringvalue, ValueType, NOW() FROM sys_jsondata WHERE UUID = v_uuid and valuetype <> 'OBJECT' and valuetype <> 'ARRAY'; -- 測試時先 Mark DELETE FROM sys_jsondata WHERE UUID = v_uuid; -- 根據操作類型調用不同副程式 IF p_action IN ('C', 'Insert') THEN CALL orm_exec_insert_v2(p_tablename, p_pk, p_action, v_uuid, v_userid); ELSEIF p_action IN ('U', 'Update') THEN CALL orm_exec_update_v2(p_tablename, p_pk, p_action, v_uuid, v_userid); ELSEIF p_action IN ('D', 'Delete') THEN CALL orm_api_kernel_v2(p_tablename, p_pk, p_action, v_uuid, 1); END IF; -- 存檔後過帳機制 CALL orm_exec_aftersave_v2(p_tablename, p_pk, p_action, v_userid); -- 提交事務 COMMIT; ELSEIF p_action IN ('P', 'Page') THEN -- 核心的 orm 程式, 取得顯示在 DataTable 的分頁資料 CALL orm_exec_page_v2(p_tablename, p_pk, v_userid, p_paras); END IF; END // DELIMITER ;