Files
Omni_orm.db/orm_exec_page_v2.txt
T
2026-03-10 14:27:48 +08:00

193 lines
6.5 KiB
Plaintext

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 版
2 Michael 2026/03/09 欄位加入 ma. 若擴充欄位檔 sys_joinfields 有定義
*/
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;
IF _joinfields IS NOT NULL AND _joinfields <> '' THEN
SET _alias = 'ma.';
SET _tbl_alias = ' ma ';
ELSE
SET _alias = '';
SET _tbl_alias = '';
END IF;
-- 統一加 alias 邏輯
IF LOCATE('ma.', _orderby) = 0 THEN
SET _orderby = CONCAT(_alias, _orderby);
END IF;
-- 應該在此處把相關欄位都加上 alias 2026/03/09 Michael
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 ', ''),
_alias, 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 ;