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 ;
