first commit
This commit is contained in:
@@ -0,0 +1,345 @@
|
||||
DELIMITER //
|
||||
|
||||
CREATE OR REPLACE PROCEDURE orm_api_kernel_v2(
|
||||
IN p_tablename VARCHAR(100),
|
||||
IN p_pk VARCHAR(100), -- primary key(for update delete)
|
||||
IN p_action VARCHAR(20), -- CRUD
|
||||
IN p_uuid VARCHAR(100),
|
||||
IN p_json_id INT
|
||||
)
|
||||
/*
|
||||
Function : 通用 orm-api 根据传入参数及设定,智能生成相应SQL
|
||||
Description: 模仿 ORM 设定,让前端程序只需传入参数就能执行增删查改基本功能
|
||||
Build Date : 2024-03-20
|
||||
|
||||
call orm_api_kernel_v2('pms_sprint','sprintid','U','uuid-20250803_2',0);
|
||||
|
||||
Modify History
|
||||
Item Who Date Modify Docs
|
||||
==== ========== ========== ================================================
|
||||
1 Developer 2024/03/20 从 MS-SQL v2 版本转换为 MariaDB 版本并优化
|
||||
*/
|
||||
BEGIN
|
||||
DECLARE v_field_identity VARCHAR(100);
|
||||
DECLARE v_fields TEXT;
|
||||
DECLARE v_datas TEXT;
|
||||
DECLARE v_updatedatas TEXT;
|
||||
DECLARE v_pkwhere TEXT;
|
||||
DECLARE v_sql LONGTEXT;
|
||||
DECLARE v_pk_cnt INT;
|
||||
DECLARE v_pk_no INT;
|
||||
DECLARE v_max_no VARCHAR(20);
|
||||
DECLARE v_bill_uuid VARCHAR(100);
|
||||
DECLARE v_bill_head VARCHAR(20);
|
||||
DECLARE v_middlefield VARCHAR(100);
|
||||
DECLARE v_dest_table VARCHAR(100);
|
||||
DECLARE v_pk_id VARCHAR(50);
|
||||
DECLARE v_fieldname VARCHAR(100);
|
||||
DECLARE v_contents LONGTEXT;
|
||||
DECLARE v_fieldtype VARCHAR(20);
|
||||
DECLARE v_quot CHAR(1);
|
||||
DECLARE v_cnt INT;
|
||||
DECLARE v_cnt2 INT;
|
||||
DECLARE v_maxcount INT;
|
||||
DECLARE v_currid INT;
|
||||
DECLARE v_nextrowid INT;
|
||||
DECLARE v_crlf VARCHAR(2);
|
||||
|
||||
-- 创建临时表存储JSON数据
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS temp_jsondata (
|
||||
parent_id INT,
|
||||
json_key VARCHAR(100),
|
||||
json_value LONGTEXT,
|
||||
ValueType VARCHAR(20),
|
||||
rowid INT AUTO_INCREMENT PRIMARY KEY
|
||||
);
|
||||
|
||||
-- 临时表用于同步删除
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS temp_sync_del (
|
||||
dest_table VARCHAR(100),
|
||||
pk_id VARCHAR(50),
|
||||
rowid INT AUTO_INCREMENT PRIMARY KEY
|
||||
);
|
||||
|
||||
-- 临时表用于避免重复字段名
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS temp_comp_json (
|
||||
fieldname VARCHAR(100)
|
||||
);
|
||||
|
||||
-- 清空临时表
|
||||
TRUNCATE TABLE temp_jsondata;
|
||||
TRUNCATE TABLE temp_sync_del;
|
||||
TRUNCATE TABLE temp_comp_json;
|
||||
|
||||
-- 将传入参数转为JSON数据(多筆 Grid 資料寫入)
|
||||
IF p_json_id = 1 then
|
||||
INSERT INTO temp_jsondata (parent_id, json_key, json_value, ValueType)
|
||||
SELECT parent_id, json_key, json_value, ValueType
|
||||
FROM orm_json_tmp
|
||||
WHERE uuid = p_uuid;
|
||||
else
|
||||
INSERT INTO temp_jsondata (parent_id, json_key, json_value, ValueType)
|
||||
SELECT parent_id, json_key, json_value, ValueType
|
||||
FROM orm_json_tmp
|
||||
WHERE uuid = p_uuid AND parent_id = FLOOR(p_json_id / 1000) and object_id = p_json_id - FLOOR(p_json_id / 1000)*1000;
|
||||
end if;
|
||||
|
||||
-- 获取自增字段
|
||||
SELECT COLUMN_NAME INTO v_field_identity
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = p_tablename
|
||||
AND EXTRA = 'auto_increment'
|
||||
LIMIT 1;
|
||||
|
||||
-- 初始化变量
|
||||
SET v_fields = '';
|
||||
SET v_datas = '';
|
||||
SET v_pkwhere = '';
|
||||
SET v_updatedatas = '';
|
||||
SET v_pk_cnt = 0;
|
||||
SET v_bill_uuid = '';
|
||||
SET v_bill_head = '';
|
||||
SET v_crlf = CONCAT(CHAR(13), CHAR(10));
|
||||
|
||||
-- 获取记录数
|
||||
SELECT COUNT(*) INTO v_maxcount FROM temp_jsondata;
|
||||
SELECT MIN(rowid) INTO v_currid FROM temp_jsondata;
|
||||
|
||||
-- 遍历JSON数据构建SQL
|
||||
WHILE v_currid <= v_maxcount DO
|
||||
-- 获取当前记录
|
||||
SELECT json_key, IFNULL(json_value, ''), ValueType
|
||||
INTO v_fieldname, v_contents, v_fieldtype
|
||||
FROM temp_jsondata
|
||||
WHERE rowid = v_currid;
|
||||
|
||||
-- 设置引号
|
||||
IF lower(v_fieldtype) = 'string' THEN
|
||||
SET v_quot = '''';
|
||||
ELSE
|
||||
SET v_quot = '';
|
||||
END IF;
|
||||
|
||||
-- 记录billno和uuid用于MD更新
|
||||
IF v_fieldname = 'uuid' THEN
|
||||
SET v_bill_uuid = v_contents;
|
||||
END IF;
|
||||
IF v_fieldname = 'billno' THEN
|
||||
SET v_bill_head = v_contents;
|
||||
END IF;
|
||||
|
||||
-- 检查字段是否存在
|
||||
SELECT COUNT(*) INTO v_cnt
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = p_tablename AND COLUMN_NAME = v_fieldname;
|
||||
|
||||
SELECT COUNT(*) INTO v_cnt2
|
||||
FROM temp_comp_json
|
||||
WHERE fieldname = v_fieldname;
|
||||
|
||||
-- 如果字段存在且未处理过
|
||||
IF v_cnt > 0 AND v_cnt2 <= 0 THEN
|
||||
-- 记录主键内容
|
||||
SELECT COUNT(*) INTO v_pk_no
|
||||
FROM (
|
||||
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(p_pk, ',', numbers.n), ',', -1) AS col
|
||||
FROM (
|
||||
SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
|
||||
SELECT 4 UNION ALL SELECT 5 -- 假设最多5个主键字段
|
||||
) numbers
|
||||
WHERE numbers.n <= LENGTH(p_pk) - LENGTH(REPLACE(p_pk, ',', '')) + 1
|
||||
) AS split_pk
|
||||
WHERE col = v_fieldname;
|
||||
|
||||
IF v_pk_no > 0 THEN
|
||||
IF v_pk_cnt >= 1 THEN
|
||||
UPDATE sys_transaction SET para02 = v_contents WHERE tablename = p_tablename;
|
||||
ELSE
|
||||
UPDATE sys_transaction SET para01 = v_contents WHERE tablename = p_tablename;
|
||||
END IF;
|
||||
SET v_pk_cnt = v_pk_cnt + 1;
|
||||
END IF;
|
||||
|
||||
-- 非自增字段处理
|
||||
IF IFNULL(v_field_identity, '') <> v_fieldname THEN
|
||||
SET v_fields = CONCAT(v_fields, v_fieldname, ',');
|
||||
|
||||
-- 构建INSERT值
|
||||
IF p_action = 'C' OR p_action = 'Insert' THEN
|
||||
SET v_datas = CONCAT(v_datas, v_quot, v_contents, v_quot, ',');
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- 构建UPDATE语句
|
||||
IF (p_action = 'U' OR p_action = 'Update') AND v_pk_no = 0 THEN
|
||||
-- 处理日期格式
|
||||
IF SUBSTRING(v_contents, 11, 19) = 'T08:00:00.000+08:00' THEN
|
||||
SET v_contents = SUBSTRING(v_contents, 1, 10);
|
||||
END IF;
|
||||
|
||||
SET v_updatedatas = CONCAT(v_updatedatas, v_fieldname, ' = ', v_quot, v_contents, v_quot, ',');
|
||||
END IF;
|
||||
|
||||
-- 构建WHERE条件
|
||||
IF v_pk_no > 0 THEN
|
||||
SET v_pkwhere = CONCAT(v_pkwhere, v_fieldname, ' = ', v_quot, v_contents, v_quot, ' AND ');
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- 记录已处理字段
|
||||
INSERT INTO temp_comp_json VALUES (v_fieldname);
|
||||
|
||||
-- 获取下一行
|
||||
SELECT MIN(rowid) INTO v_nextrowid
|
||||
FROM temp_jsondata
|
||||
WHERE rowid > v_currid;
|
||||
SET v_currid = v_nextrowid;
|
||||
END WHILE;
|
||||
|
||||
-- 处理没有主键的情况
|
||||
IF v_pk_cnt = 0 THEN
|
||||
SELECT middlefield INTO v_middlefield
|
||||
FROM sys_transaction
|
||||
WHERE tablename = p_tablename
|
||||
LIMIT 1;
|
||||
|
||||
SELECT json_value INTO v_contents
|
||||
FROM temp_jsondata
|
||||
WHERE json_key = v_middlefield
|
||||
LIMIT 1;
|
||||
|
||||
IF LENGTH(v_contents) <= 1000 THEN
|
||||
UPDATE sys_transaction SET para01 = v_contents WHERE tablename = p_tablename;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- 处理自增主键情况
|
||||
IF (p_action = 'C' OR p_action = 'Insert') AND (p_pk = v_field_identity) THEN
|
||||
UPDATE sys_transaction SET para01 = 'identity' WHERE tablename = p_tablename;
|
||||
END IF;
|
||||
|
||||
-- 移除末尾的逗号或AND
|
||||
IF v_fields <> '' THEN
|
||||
-- SET v_fields = SUBSTRING(v_fields, 1, LENGTH(v_fields) - 1);
|
||||
SET v_fields = TRIM(TRAILING ',' FROM v_fields);
|
||||
END IF;
|
||||
|
||||
IF v_datas <> '' THEN
|
||||
-- SET v_datas = SUBSTRING(v_datas, 1, LENGTH(v_datas) - 1);
|
||||
SET v_datas = TRIM(TRAILING ',' FROM v_datas);
|
||||
END IF;
|
||||
|
||||
IF v_updatedatas <> '' THEN
|
||||
-- SET v_updatedatas = SUBSTRING(v_updatedatas, 1, LENGTH(v_updatedatas) - 1);
|
||||
SET v_updatedatas = TRIM(TRAILING ',' FROM v_updatedatas);
|
||||
END IF;
|
||||
|
||||
IF v_pkwhere <> '' THEN
|
||||
SET v_pkwhere = SUBSTRING(v_pkwhere, 1, LENGTH(v_pkwhere) - 5);
|
||||
END IF;
|
||||
|
||||
-- 构建基础SQL
|
||||
IF p_action = 'C' OR p_action = 'Insert' THEN
|
||||
SET v_sql = CONCAT('INSERT INTO ', p_tablename, ' (', v_fields, ') VALUES (', v_datas, ')');
|
||||
|
||||
-- 加入 M-D 的 D 同步 billno update
|
||||
INSERT INTO temp_sync_del (dest_table, pk_id)
|
||||
SELECT dest_table, pk_id FROM sys_sync_delete_detail WHERE tablename = p_tablename;
|
||||
|
||||
-- 处理同步更新
|
||||
SELECT COUNT(*) INTO v_maxcount FROM temp_sync_del;
|
||||
SELECT MIN(rowid) INTO v_currid FROM temp_sync_del;
|
||||
|
||||
WHILE v_currid <= v_maxcount DO
|
||||
SELECT dest_table, pk_id INTO v_dest_table, v_pk_id
|
||||
FROM temp_sync_del
|
||||
WHERE rowid = v_currid;
|
||||
|
||||
-- 检查目标表是否有uuid字段
|
||||
SELECT COUNT(*) INTO v_cnt
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = v_dest_table AND COLUMN_NAME = 'uuid';
|
||||
|
||||
IF v_cnt > 0 THEN
|
||||
SET v_sql = CONCAT(v_sql, ';\n',
|
||||
'UPDATE ', v_dest_table, ' SET ', IFNULL(v_pk_id, 'billno'), ' = ''',
|
||||
v_bill_head, ''' WHERE uuid = ''', v_bill_uuid, '''');
|
||||
END IF;
|
||||
|
||||
-- 获取下一行
|
||||
SELECT MIN(rowid) INTO v_nextrowid
|
||||
FROM temp_sync_del
|
||||
WHERE rowid > v_currid;
|
||||
SET v_currid = v_nextrowid;
|
||||
END WHILE;
|
||||
|
||||
ELSEIF p_action = 'U' OR p_action = 'Update' THEN
|
||||
SET v_sql = CONCAT('UPDATE ', p_tablename, ' SET ', v_updatedatas, ' WHERE ', v_pkwhere);
|
||||
|
||||
ELSEIF p_action = 'D' OR p_action = 'Delete' THEN
|
||||
-- 基础删除语句
|
||||
SET v_sql = CONCAT('DELETE FROM ', p_tablename, ' WHERE ', v_pkwhere);
|
||||
|
||||
-- 处理同步删除
|
||||
INSERT INTO temp_sync_del (dest_table, pk_id)
|
||||
SELECT dest_table, pk_id FROM sys_sync_delete_detail WHERE tablename = p_tablename;
|
||||
|
||||
SELECT COUNT(*) INTO v_maxcount FROM temp_sync_del;
|
||||
SELECT MIN(rowid) INTO v_currid FROM temp_sync_del;
|
||||
|
||||
WHILE v_currid <= v_maxcount DO
|
||||
SELECT dest_table, pk_id INTO v_dest_table, v_pk_id
|
||||
FROM temp_sync_del
|
||||
WHERE rowid = v_currid;
|
||||
|
||||
-- 解决 M-D 的 pk 栏名不同的问题
|
||||
IF IFNULL(v_pk_id, '') = '' THEN
|
||||
SET v_sql = CONCAT(v_sql, ';', v_crlf,
|
||||
'DELETE FROM ', v_dest_table, ' WHERE ', v_pkwhere, ';');
|
||||
ELSE
|
||||
SET v_sql = CONCAT(v_sql, ';', v_crlf,
|
||||
'DELETE FROM ', v_dest_table, ' WHERE ',
|
||||
REPLACE(v_pkwhere, p_pk, v_pk_id), ';');
|
||||
END IF;
|
||||
|
||||
-- 获取下一行
|
||||
SELECT MIN(rowid) INTO v_nextrowid
|
||||
FROM temp_sync_del
|
||||
WHERE rowid > v_currid;
|
||||
SET v_currid = v_nextrowid;
|
||||
END WHILE;
|
||||
END IF;
|
||||
|
||||
-- 处理日期格式问题
|
||||
IF INSTR(v_sql, '000+08:00') > 0 THEN
|
||||
SET v_sql = REPLACE(v_sql, '000+08:00', '000Z');
|
||||
END IF;
|
||||
|
||||
-- 执行SQL
|
||||
/* Mariadb 不支援動態語句多 sql, 只能切割
|
||||
GET DIAGNOSTICS CONDITION 1
|
||||
@sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
|
||||
|
||||
SELECT 1 AS code, CONCAT('Error: ', @errno, ' (', @sqlstate, '): ', @text) AS msg, 0 AS recno;
|
||||
SELECT v_sql AS error_sql;
|
||||
END;
|
||||
|
||||
-- 返回成功结果
|
||||
SELECT 0 AS code, 'ok' AS msg, 0 AS recno;
|
||||
|
||||
-- 执行SQL
|
||||
SET @dynamic_sql = v_sql;
|
||||
PREPARE stmt FROM @dynamic_sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
END;
|
||||
*/
|
||||
call execute_multiple_sql(v_sql);
|
||||
|
||||
-- 清理临时表
|
||||
DROP TEMPORARY TABLE IF EXISTS temp_jsondata;
|
||||
DROP TEMPORARY TABLE IF EXISTS temp_sync_del;
|
||||
DROP TEMPORARY TABLE IF EXISTS temp_comp_json;
|
||||
END //
|
||||
|
||||
DELIMITER ;
|
||||
Reference in New Issue
Block a user