DELIMITER $$ CREATE OR REPLACE PROCEDURE orm_exec_page_v2 ( IN _tablename VARCHAR(200), IN _pk VARCHAR(100), IN _userid VARCHAR(100), IN _paras TEXT ) /* Function : orm_api_v2 [分頁查詢]的核心程式, 智慧的組出相應的 sql, 被 orm_api_v2 呼叫使用 Description: 要特別注意傳入的參數正確性, 下面是一個正確的 case call orm_api_v2('b013a91a-daf1-11f0-a07a-d8bbc15c1404','basperson','personid','P','1^100^personid^*^^^personcname^林^^'); Build Date : 2025/07/11 Modify History Item Who Date Modify Docs ==== ========== ========== ================================================ 1 Michael 2025/07/11 根據 ms-sql 的版本, 利用 ChatGPT/DeepSeek 等AI, 改寫為 Mariadb 版 */ BEGIN DECLARE _pageno INT DEFAULT 1; DECLARE _pagerec INT DEFAULT 10; DECLARE _orderby TEXT DEFAULT ''; DECLARE _udf_fields TEXT DEFAULT '*'; DECLARE _wheresql TEXT DEFAULT ''; DECLARE _wheresql_org TEXT DEFAULT ''; DECLARE _where_value TEXT DEFAULT ''; DECLARE _where_fields TEXT DEFAULT ''; DECLARE _where_field TEXT DEFAULT ''; DECLARE _where_idvalue TEXT DEFAULT ''; DECLARE _menuid TEXT DEFAULT ''; DECLARE _jointables TEXT DEFAULT ''; DECLARE _joinfields TEXT DEFAULT ''; DECLARE _tbl_alias TEXT DEFAULT ''; DECLARE _alias TEXT DEFAULT ''; DECLARE _startrec INT DEFAULT 0; DECLARE _sql TEXT; DECLARE _sql_cnt TEXT; DECLARE _dtc INT DEFAULT 0; DECLARE _guid VARCHAR(100); -- DECLARE v_field VARCHAR(200); DECLARE v_pos INT DEFAULT 1; DECLARE v_count INT; -- 錯誤處理 /* DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SELECT '9999' AS code, '資料庫操作錯誤' AS msg; END; */ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT; SELECT 1 AS code, CONCAT('Error: ', @errno, ' (', @sqlstate, '): ', @text) AS msg; END; SET _guid = UUID(); CALL gp_split(_guid, _paras, '^'); -- 使用 split 暫存表方式處理參數 SELECT col INTO _pageno FROM _split WHERE guid = _guid and rowid = 1; SELECT col INTO _pagerec FROM _split WHERE guid = _guid and rowid = 2; SELECT col INTO _orderby FROM _split WHERE guid = _guid and rowid = 3; SELECT col INTO _udf_fields FROM _split WHERE guid = _guid and rowid = 4; SELECT col INTO _wheresql_org FROM _split WHERE guid = _guid and rowid = 5; SELECT col INTO _menuid FROM _split WHERE guid = _guid and rowid = 6; SELECT col INTO _where_fields FROM _split WHERE guid = _guid and rowid = 7; SELECT col INTO _where_value FROM _split WHERE guid = _guid and rowid = 8; SELECT col INTO _where_field FROM _split WHERE guid = _guid and rowid = 9; SELECT col INTO _where_idvalue FROM _split WHERE guid = _guid and rowid = 10; DELETE FROM _split WHERE guid = _guid; -- 預設排序欄位 IF _orderby IS NULL OR _orderby = '' THEN SET _orderby = _pk; END IF; IF _udf_fields IS NULL OR _udf_fields = '' THEN SET _udf_fields = '*'; END IF; -- 防錯 SET _jointables = ''; IF _menuid IS NOT NULL AND _menuid <> '' THEN SELECT joinfields, jointables INTO _joinfields, _jointables FROM sys_joinfields WHERE menuid = _menuid; SET _alias = 'ma.'; SET _tbl_alias = ' ma '; IF LOCATE('ma.', _orderby) = 0 THEN SET _orderby = CONCAT(_alias, _orderby); END IF; END IF; -- 建立 WHERE 條件 IF _where_value IS NOT NULL AND _where_value <> '' THEN IF LOCATE(',', _where_fields) > 0 THEN -- SET _wheresql = REPLACE(_where_fields, ',', CONCAT(' LIKE ',"'",'%', _where_value, '%', "'", ' OR ', _alias)); -- SET _wheresql = CONCAT(' WHERE (', _alias, _where_fields, ' LIKE ', QUOTE(CONCAT('%', _where_value, '%')), ')'); -- 改寫, 本段程式目的是要多欄位 like 查詢 SET v_count = LENGTH(_where_fields) - LENGTH(REPLACE(_where_fields, ',', '')) + 1; WHILE v_pos <= v_count DO SET v_field = TRIM( SUBSTRING_INDEX( SUBSTRING_INDEX(_where_fields, ',', v_pos), ',', -1 ) ); SET _wheresql = CONCAT( _wheresql, IF(v_pos > 1, ' OR ', ''), v_field, ' LIKE ', QUOTE(CONCAT('%', _where_value, '%')) ); SET v_pos = v_pos + 1; END WHILE; SET _wheresql = CONCAT(' WHERE (', _wheresql, ')'); -- ELSE SET _wheresql = CONCAT(' WHERE ', _alias, _where_fields, ' LIKE ', QUOTE(CONCAT('%', _where_value, '%'))); END IF; END IF; -- debug -- select concat('where9: ',_wheresql); -- 加入網址參數條件 IF _where_idvalue IS NOT NULL AND _where_idvalue <> '' THEN IF _wheresql = '' THEN SET _wheresql = CONCAT(' WHERE ', _alias, _where_field, ' = ', QUOTE(_where_idvalue)); ELSE SET _wheresql = CONCAT(_wheresql, ' AND ', _alias, _where_field, ' = ', QUOTE(_where_idvalue)); END IF; END IF; -- 加上前端傳入的原始 WHERE IF _wheresql_org IS NOT NULL AND _wheresql_org <> '' THEN SET _wheresql_org = REPLACE(_wheresql_org, '~', "'"); IF _wheresql = '' THEN SET _wheresql = CONCAT(' WHERE ', _wheresql_org); ELSE SET _wheresql = CONCAT(_wheresql, ' AND ', _wheresql_org); END IF; END IF; -- 計算 offset SET _startrec = (_pageno - 1) * _pagerec; -- 查詢筆數 SET _sql_cnt = CONCAT('SELECT COUNT(*) INTO @dtc FROM ', _tablename, _tbl_alias, ' ', _wheresql); PREPARE stmt_cnt FROM _sql_cnt; EXECUTE stmt_cnt; DEALLOCATE PREPARE stmt_cnt; SELECT 0 AS code, 'ok' AS msg, @dtc AS recno; -- SELECT 'debug' AS code, _sql_cnt AS msg, @dtc AS recno; -- 組合查詢 SQL IF _jointables IS NULL OR _jointables = '' THEN SET _sql = CONCAT('SELECT ', _udf_fields, ' FROM ', _tablename, _tbl_alias, ' ', _wheresql, ' ORDER BY ', _orderby, ' LIMIT ', _pagerec, ' OFFSET ', _startrec); ELSE SET _sql = CONCAT('SELECT ', _joinfields, ' FROM ', _tablename, _tbl_alias, _jointables, ' ', _wheresql, ' ORDER BY ', _orderby, ' LIMIT ', _pagerec, ' OFFSET ', _startrec); END IF; -- 執行查詢 PREPARE stmt FROM _sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END$$ DELIMITER ;