The new MySQL 5.7 version has some great features.
One of them is the ‘JSON data’ type. We can use it for column of table like ‘Virtual Colunm’ with Indexing.
But, ‘JSON data’ is also useful for stored procedure. Because we can compact parameters and the procedure could be more flexible.I made the procedures for table insert/update via JSON parameter.
When I apply them to my project, data-handling codes in the application decreased dramatically.
(These procedures impliment ‘MySQL Procedure Pattern for Nested Transaction‘)
The code below is an old version. The latest source code is in Github. |
DELIMITER $ CREATE PROCEDURE `sp_do_insert_table_by_json`( IN `i_columns` JSON, IN `i_table` VARCHAR(64), IN `i_schema` VARCHAR(64), OUT `o_result` JSON ) body:BEGIN /** General Procedure for Table Inserting from JSON 2016-06 Aiden Kihyun Kim Parameters IN `i_columns` JSON : Columns {"col1_name":col1_value, "col2_name":"col2_value", ... } IN `i_table` VARCHAR(64) : Table name IN `i_schema` VARCHAR(64) : Database name OUT `o_result` JSON : {"return":return_code, "row_count":row_count, "last_insert_id":last_insert_id} **/ DECLARE v_autocommit BIT DEFAULT @@AUTOCOMMIT; DECLARE v_schema VARCHAR(64) DEFAULT NULL; DECLARE c_done BIT DEFAULT FALSE; DECLARE v_column VARCHAR(64) DEFAULT NULL; DECLARE v_column_key VARCHAR(64) DEFAULT NULL; DECLARE v_extra VARCHAR(64) DEFAULT NULL; DECLARE v_type VARCHAR(64) DEFAULT NULL; DECLARE v_query1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE v_query2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE require_rollback CONDITION FOR SQLSTATE '45000'; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET o_result = JSON_SET(o_result, '$.return', -999); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1062 BEGIN SET o_result = JSON_SET(o_result, '$.return', -901); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1216,1452 BEGIN SET o_result = JSON_SET(o_result, '$.return', -902); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1217,1451 BEGIN SET o_result = JSON_SET(o_result, '$.return', -903); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR require_rollback BEGIN IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; SET o_result = JSON_OBJECT('return', -1, 'row_count', -1); SET v_schema = IF(i_schema IS NULL, database(), v_schema); BEGIN DECLARE c_column CURSOR FOR SELECT COLUMN_NAME, COLUMN_KEY, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=v_schema AND TABLE_NAME=i_table AND EXTRA<>'VIRTUAL GENERATED' ORDER BY ORDINAL_POSITION; DECLARE CONTINUE HANDLER FOR NOT FOUND SET c_done = TRUE; OPEN c_column; cursor_loop: LOOP FETCH c_column INTO v_column, v_column_key, v_extra; IF c_done THEN LEAVE cursor_loop; END IF; IF (v_column_key='PRI' AND v_extra='auto_increment') THEN SET o_result = JSON_SET(o_result, '$.last_insert_id', NULL); ELSEIF JSON_CONTAINS_PATH(i_columns,'one',CONCAT('$.',v_column)) THEN SET v_query1 = CONCAT(IF(v_query1 IS NULL,'',CONCAT(v_query1,', ')), '`', v_column, '`'); SET v_query2 = IF(v_query2 IS NULL,'',CONCAT(v_query2,', ')); SET v_type = JSON_TYPE(JSON_EXTRACT(i_columns,CONCAT('$.',v_column))); IF v_type='NULL' THEN SET v_query2 = CONCAT(v_query2, 'NULL'); ELSEIF v_type IN ('INTEGER','DOUBLE','DECIMAL','BIT') THEN SET v_query2 = CONCAT(v_query2, JSON_EXTRACT(i_columns, CONCAT('$.',v_column))); ELSE SET v_query2 = CONCAT(v_query2, '''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(i_columns, CONCAT('$.',v_column))),'''',''''''), ''''); END IF; END IF; END LOOP; CLOSE c_column; END; IF (v_query1 IS NULL) THEN SET o_result = JSON_SET(o_result, '$.return', -101); SIGNAL require_rollback; END IF; IF (v_query2 IS NULL) THEN SET o_result = JSON_SET(o_result, '$.return', -102); SIGNAL require_rollback; END IF; IF (v_autocommit = 1) THEN SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION autocommit = 0; START TRANSACTION; END IF; SET @query = CONCAT('INSERT INTO `', v_schema, '`.`', i_table, '` (', v_query1, ') VALUES (', v_query2, ')'); PREPARE stmt FROM @query; EXECUTE stmt; SELECT ROW_COUNT(), LAST_INSERT_ID() INTO @row_count, @last_insert_id; DEALLOCATE PREPARE stmt; IF (v_autocommit = 1) AND (@@AUTOCOMMIT = 0) THEN COMMIT; SET SESSION autocommit = 1; END IF; IF JSON_CONTAINS_PATH(o_result,'one','$.last_insert_id') THEN SET o_result = JSON_SET(o_result, '$.return', 0, '$.row_count', @row_count, '$.last_insert_id', @last_insert_id); ELSE SET o_result = JSON_SET(o_result, '$.return', 0, '$.row_count', @row_count); END IF; END$ DELIMITER ;
DELIMITER $ CREATE PROCEDURE `sp_do_update_table_by_json`( IN `i_columns` JSON, IN `i_conditions` JSON, IN `i_table` VARCHAR(64), IN `i_schema` VARCHAR(64), OUT `o_result` JSON ) body:BEGIN /** General Procedure for Table Updating from JSON 2016-06 Aiden Kihyun Kim Parameters IN `i_columns` JSON : Columns {"col1_name":col1_value, "col2_name":"col2_value", ... } IN `i_conditions` JSON : Search conditions {"col1_name":col1_value, "col2_name":"col2_value", ... } IN `i_table` VARCHAR(64) : Table name IN `i_schema` VARCHAR(64) : Database name OUT `o_result` JSON : {"return":return_code, "row_count":row_count} **/ DECLARE v_autocommit BIT DEFAULT @@AUTOCOMMIT; DECLARE v_schema VARCHAR(64) DEFAULT NULL; DECLARE c_done BIT DEFAULT FALSE; DECLARE v_column VARCHAR(64) DEFAULT NULL; DECLARE v_column_key VARCHAR(64) DEFAULT NULL; DECLARE v_extra VARCHAR(64) DEFAULT NULL; DECLARE v_type VARCHAR(64) DEFAULT NULL; DECLARE v_array JSON DEFAULT NULL; DECLARE v_query1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE v_query2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE require_rollback CONDITION FOR SQLSTATE '45000'; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET o_result = JSON_SET(o_result, '$.return', -999); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1062 BEGIN SET o_result = JSON_SET(o_result, '$.return', -901); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1216,1452 BEGIN SET o_result = JSON_SET(o_result, '$.return', -902); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1217,1451 BEGIN SET o_result = JSON_SET(o_result, '$.return', -903); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR require_rollback BEGIN IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; SET o_result = JSON_OBJECT('return', -1, 'row_count', -1); SET v_schema = IF(i_schema IS NULL, database(), v_schema); BEGIN DECLARE c_column CURSOR FOR SELECT COLUMN_NAME, COLUMN_KEY, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=v_schema AND TABLE_NAME=i_table AND EXTRA<>'VIRTUAL GENERATED' ORDER BY ORDINAL_POSITION; DECLARE CONTINUE HANDLER FOR NOT FOUND SET c_done = TRUE; OPEN c_column; cursor_loop: LOOP FETCH c_column INTO v_column, v_column_key, v_extra; IF c_done THEN LEAVE cursor_loop; END IF; IF JSON_CONTAINS_PATH(i_columns,'one',CONCAT('$.',v_column)) THEN SET v_type = JSON_TYPE(JSON_EXTRACT(i_columns,CONCAT('$.',v_column))); SET v_query1 = CONCAT(IF(v_query1 IS NULL,'',CONCAT(v_query1,', ')), '`', v_column, '`='); IF v_type='NULL' THEN SET v_query1 = CONCAT(v_query1, 'NULL'); ELSEIF v_type IN ('INTEGER','DOUBLE','DECIMAL','BIT') THEN SET v_query1 = CONCAT(v_query1, JSON_EXTRACT(i_columns, CONCAT('$.',v_column))); ELSE SET v_query1 = CONCAT(v_query1, '''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(i_columns, CONCAT('$.',v_column))),'''',''''''), ''''); END IF; END IF; IF JSON_CONTAINS_PATH(i_conditions,'one',CONCAT('$.',v_column)) THEN SET v_type = JSON_TYPE(JSON_EXTRACT(i_conditions,CONCAT('$.',v_column))); SET v_query2 = CONCAT(IF(v_query2 IS NULL,'',CONCAT(v_query2,' AND ')), '`', v_column, '`'); IF v_type='NULL' THEN SET v_query2 = CONCAT(v_query2, '=NULL'); ELSEIF v_type IN ('INTEGER','DOUBLE','DECIMAL','BIT') THEN SET v_query2 = CONCAT(v_query2, '=', JSON_EXTRACT(i_conditions, CONCAT('$.',v_column))); ELSEIF v_type IN ('ARRAY','OBJECT') THEN SET v_array = JSON_EXTRACT(i_conditions,CONCAT('$.',v_column)); IF v_type = 'OBJECT' THEN IF JSON_CONTAINS_PATH(v_array,'one',CONCAT('$."2"')) THEN SET v_array = JSON_ARRAY(JSON_EXTRACT(v_array,'$."0"'),JSON_EXTRACT(v_array,'$."1"'),JSON_EXTRACT(v_array,'$."2"')); ELSE SET v_array = JSON_ARRAY(JSON_EXTRACT(v_array,'$."0"'),JSON_EXTRACT(v_array,'$."1"')); END IF; END IF; IF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'BETWEEN' THEN SET v_query2 = CONCAT(v_query2, ' BETWEEN ', JSON_EXTRACT(v_array,'$[1]'), ' AND ', JSON_EXTRACT(v_array,'$[2]')); ELSEIF JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]')) IN ('<','<=','>','>=') THEN SET v_query2 = CONCAT(v_query2, JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]')), JSON_EXTRACT(v_array,'$[1]')); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'LIKE' THEN SET v_query2 = CONCAT(v_query2, ' LIKE ''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')),'''',''''''), ''''); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'IN' THEN SET v_query2 = CONCAT(v_query2, ' IN (', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')), ')'); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'IS' THEN SET v_query2 = CONCAT(v_query2, ' IS ', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]'))); END IF; ELSE SET v_query2 = CONCAT(v_query2, '=''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(i_conditions, CONCAT('$.',v_column))),'''',''''''), ''''); END IF; END IF; END LOOP; CLOSE c_column; END; IF (v_query1 IS NULL) THEN SET o_result = JSON_SET(o_result, '$.return', -101); SIGNAL require_rollback; END IF; IF (v_query2 IS NULL) THEN SET o_result = JSON_SET(o_result, '$.return', -102); SIGNAL require_rollback; END IF; IF (v_autocommit = 1) THEN SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION autocommit = 0; START TRANSACTION; END IF; SET @query = CONCAT('UPDATE `', v_schema, '`.`', i_table, '` SET ', v_query1, ' WHERE ', v_query2); PREPARE stmt FROM @query; EXECUTE stmt; SELECT ROW_COUNT() INTO @row_count; DEALLOCATE PREPARE stmt; IF (v_autocommit = 1) AND (@@AUTOCOMMIT = 0) THEN COMMIT; SET SESSION autocommit = 1; END IF; SET o_result = JSON_SET(o_result, '$.return', 0, '$.row_count', @row_count); END$ DELIMITER ;
DELIMITER $ CREATE PROCEDURE `sp_do_delete_table_by_json`( IN `i_conditions` JSON, IN `i_table` VARCHAR(64), IN `i_schema` VARCHAR(64), OUT `o_result` JSON ) body:BEGIN /** General Procedure for Table Row Deleting from JSON 2016-06 Aiden Kihyun Kim Parameters IN `i_conditions` JSON : Search conditions {"col1_name":col1_value, "col2_name":"col2_value", ... } IN `i_table` VARCHAR(64) : Table name IN `i_schema` VARCHAR(64) : Database name OUT `o_result` JSON : {"return":return_code, "row_count":row_count} **/ DECLARE v_autocommit BIT DEFAULT @@AUTOCOMMIT; DECLARE v_schema VARCHAR(64) DEFAULT NULL; DECLARE c_done BIT DEFAULT FALSE; DECLARE v_column VARCHAR(64) DEFAULT NULL; DECLARE v_column_key VARCHAR(64) DEFAULT NULL; DECLARE v_extra VARCHAR(64) DEFAULT NULL; DECLARE v_type VARCHAR(64) DEFAULT NULL; DECLARE v_array JSON DEFAULT NULL; DECLARE v_query TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE require_rollback CONDITION FOR SQLSTATE '45000'; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SET o_result = JSON_SET(o_result, '$.return', -999); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1062 BEGIN SET o_result = JSON_SET(o_result, '$.return', -901); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1216,1452 BEGIN SET o_result = JSON_SET(o_result, '$.return', -902); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR 1217,1451 BEGIN SET o_result = JSON_SET(o_result, '$.return', -903); IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; DECLARE EXIT HANDLER FOR require_rollback BEGIN IF (v_autocommit=1) AND (@@AUTOCOMMIT=0) THEN ROLLBACK; SET SESSION autocommit = 1; END IF; END; SET o_result = JSON_OBJECT('return', -1, 'row_count', -1); SET v_schema = IF(i_schema IS NULL, database(), v_schema); BEGIN DECLARE c_column CURSOR FOR SELECT COLUMN_NAME, COLUMN_KEY, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=v_schema AND TABLE_NAME=i_table AND EXTRA<>'VIRTUAL GENERATED' ORDER BY ORDINAL_POSITION; DECLARE CONTINUE HANDLER FOR NOT FOUND SET c_done = TRUE; OPEN c_column; cursor_loop: LOOP FETCH c_column INTO v_column, v_column_key, v_extra; IF c_done THEN LEAVE cursor_loop; END IF; IF JSON_CONTAINS_PATH(i_conditions,'one',CONCAT('$.',v_column)) THEN SET v_type = JSON_TYPE(JSON_EXTRACT(i_conditions,CONCAT('$.',v_column))); SET v_query = CONCAT(IF(v_query IS NULL,'',CONCAT(v_query,' AND ')), '`', v_column, '`'); IF v_type='NULL' THEN SET v_query = CONCAT(v_query, '=NULL'); ELSEIF v_type IN ('INTEGER','DOUBLE','DECIMAL','BIT') THEN SET v_query = CONCAT(v_query, '=', JSON_EXTRACT(i_conditions, CONCAT('$.',v_column))); ELSEIF v_type IN ('ARRAY','OBJECT') THEN SET v_array = JSON_EXTRACT(i_conditions,CONCAT('$.',v_column)); IF v_type = 'OBJECT' THEN IF JSON_CONTAINS_PATH(v_array,'one',CONCAT('$."2"')) THEN SET v_array = JSON_ARRAY(JSON_EXTRACT(v_array,'$."0"'),JSON_EXTRACT(v_array,'$."1"'),JSON_EXTRACT(v_array,'$."2"')); ELSE SET v_array = JSON_ARRAY(JSON_EXTRACT(v_array,'$."0"'),JSON_EXTRACT(v_array,'$."1"')); END IF; END IF; IF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'BETWEEN' THEN SET v_query = CONCAT(v_query, ' BETWEEN ', JSON_EXTRACT(v_array,'$[1]'), ' AND ', JSON_EXTRACT(v_array,'$[2]')); ELSEIF JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]')) IN ('<','<=','>','>=') THEN SET v_query = CONCAT(v_query, JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]')), JSON_EXTRACT(v_array,'$[1]')); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'LIKE' THEN SET v_query = CONCAT(v_query, ' LIKE ''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')),'''',''''''), ''''); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'IN' THEN SET v_query = CONCAT(v_query, ' IN (', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')), ')'); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'IS' THEN SET v_query = CONCAT(v_query, ' IS ', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]'))); END IF; ELSE SET v_query = CONCAT(v_query, '=''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(i_conditions, CONCAT('$.',v_column))),'''',''''''), ''''); END IF; END IF; END LOOP; CLOSE c_column; END; IF (v_query IS NULL) THEN SET o_result = JSON_SET(o_result, '$.return', -101); SIGNAL require_rollback; END IF; IF (v_autocommit = 1) THEN SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION autocommit = 0; START TRANSACTION; END IF; SET @query = CONCAT('DELETE FROM `', v_schema, '`.`', i_table, '` WHERE ', v_query); PREPARE stmt FROM @query; EXECUTE stmt; SELECT ROW_COUNT() INTO @row_count; DEALLOCATE PREPARE stmt; IF (v_autocommit = 1) AND (@@AUTOCOMMIT = 0) THEN COMMIT; SET SESSION autocommit = 1; END IF; SET o_result = JSON_SET(o_result, '$.return', 0, '$.row_count', @row_count); END$ DELIMITER ;
DELIMITER $ CREATE PROCEDURE `sp_do_search_table_by_json`( IN `i_conditions` JSON, IN `i_table` VARCHAR(64), IN `i_schema` VARCHAR(64), OUT `o_result` JSON ) body:BEGIN /** General Procedure for Table Searching from JSON 2016-06 Aiden Kihyun Kim Parameters IN `i_conditions` JSON : Search conditions {"col1_name":col1_value, "col2_name":"col2_value", ... } IN `i_table` VARCHAR(64) : Table name IN `i_schema` VARCHAR(64) : Database name OUT `o_result` JSON : {"return":return_code, "row_count":row_count} **/ DECLARE v_schema VARCHAR(64) DEFAULT NULL; DECLARE c_done BIT DEFAULT FALSE; DECLARE v_column VARCHAR(64) DEFAULT NULL; DECLARE v_column_key VARCHAR(64) DEFAULT NULL; DECLARE v_extra VARCHAR(64) DEFAULT NULL; DECLARE v_type VARCHAR(64) DEFAULT NULL; DECLARE v_array JSON DEFAULT NULL; DECLARE v_query1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE v_query2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE v_query3 TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET o_result = JSON_SET(o_result, '$.return', -999); SET o_result = JSON_OBJECT('return', -1, 'row_count', -1); SET v_schema = IF(i_schema IS NULL, database(), v_schema); BEGIN DECLARE c_column CURSOR FOR SELECT COLUMN_NAME, COLUMN_KEY, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = v_schema AND TABLE_NAME = i_table ORDER BY ORDINAL_POSITION; DECLARE CONTINUE HANDLER FOR NOT FOUND SET c_done = TRUE; OPEN c_column; cursor_loop: LOOP FETCH c_column INTO v_column, v_column_key, v_extra; IF c_done THEN LEAVE cursor_loop; END IF; SET v_query1 = IF(v_query1 IS NULL,'',CONCAT(v_query1,', ')); IF (v_data_type = 'json') THEN SET v_query1 = CONCAT(v_query1, 'CAST(`', v_column, '` AS CHAR) AS ', v_column); ELSEIF (INSTR(v_data_type,'binary')>0) THEN SET v_query1 = CONCAT(v_query1, 'HEX(`', v_column, '`) AS ', v_column); ELSEIF (INSTR(v_data_type,'point')>0 OR INSTR(v_data_type,'linestring')>0 OR INSTR(v_data_type,'polygon')>0 OR INSTR(v_data_type,'geometry')>0) THEN SET v_query1 = CONCAT(v_query1, 'ST_AsText(`', v_column, '`) AS ', v_column); ELSE SET v_query1 = CONCAT(v_query1, '`', v_column, '`'); END IF; IF JSON_CONTAINS_PATH(i_conditions,'one',CONCAT('$.',v_column)) THEN SET v_type = JSON_TYPE(JSON_EXTRACT(i_conditions,CONCAT('$.',v_column))); IF v_type='NULL' THEN SET v_query3 = CONCAT('`', v_column, '`=NULL'); ELSEIF v_type IN ('INTEGER','DOUBLE','DECIMAL','BIT') THEN SET v_query3 = CONCAT('`', v_column, '`=', JSON_EXTRACT(i_conditions, CONCAT('$.',v_column))); ELSEIF v_type IN ('ARRAY','OBJECT') THEN SET v_array = JSON_EXTRACT(i_conditions,CONCAT('$.',v_column)); IF v_type = 'OBJECT' THEN IF JSON_CONTAINS_PATH(v_array,'one',CONCAT('$."2"')) THEN SET v_array = JSON_ARRAY(JSON_EXTRACT(v_array,'$."0"'),JSON_EXTRACT(v_array,'$."1"'),JSON_EXTRACT(v_array,'$."2"')); ELSE SET v_array = JSON_ARRAY(JSON_EXTRACT(v_array,'$."0"'),JSON_EXTRACT(v_array,'$."1"')); END IF; END IF; IF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'BETWEEN' THEN SET v_query3 = CONCAT('`', v_column, '` BETWEEN ', JSON_EXTRACT(v_array,'$[1]'), ' AND ', JSON_EXTRACT(v_array,'$[2]')); ELSEIF JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]')) IN ('<','<=','>','>=') THEN SET v_query3 = CONCAT('`', v_column, '`', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]')), JSON_EXTRACT(v_array,'$[1]')); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'LIKE' THEN SET v_query3 = CONCAT('`', v_column, '` LIKE ''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')),'''',''''''), ''''); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'IN' THEN SET v_query3 = CONCAT('`', v_column, '` IN (', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')), ')'); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'IS' THEN SET v_query3 = CONCAT('`', v_column, '` IS ', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]'))); ELSEIF UPPER(JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[0]'))) = 'MATCH' THEN SET v_query3 = CONCAT('MATCH (', v_column, ') AGAINST (''"', JSON_UNQUOTE(JSON_EXTRACT(v_array,'$[1]')), '"'' IN BOOLEAN MODE)' ); END IF; ELSE SET v_query3 = CONCAT('`', v_column, '`=''', REPLACE(JSON_UNQUOTE(JSON_EXTRACT(i_conditions, CONCAT('$.',v_column))),'''',''''''), ''''); END IF; SET v_query2 = CONCAT(IF(v_query2 IS NULL,' ',CONCAT(v_query2,' AND ')), v_query3); END IF; END LOOP; CLOSE c_column; END; IF (v_query1 IS NULL) THEN SET o_result = JSON_SET(o_result, '$.return', -101); LEAVE body; END IF; IF (v_query2 IS NULL) THEN SET v_query2 = '1=1'; END IF; SET @query = CONCAT('SELECT SQL_CALC_FOUND_ROWS ', v_query1, ' FROM `', v_schema, '`.`', i_table, '` WHERE ', v_query2); IF JSON_CONTAINS_PATH(i_conditions,'one','$.sort_field') AND JSON_TYPE(JSON_EXTRACT(i_conditions,'$.sort_field'))<>'NULL' THEN SET @query = CONCAT(@query, ' ORDER BY ', JSON_UNQUOTE(JSON_EXTRACT(i_conditions,'$.sort_field'))); IF JSON_CONTAINS_PATH(i_conditions,'one','$.sort_order') AND JSON_TYPE(JSON_EXTRACT(i_conditions,'$.sort_order'))<>'NULL' THEN SET @query = CONCAT(@query, ' ', JSON_UNQUOTE(JSON_EXTRACT(i_conditions,'$.sort_order'))); END IF; END IF; IF JSON_CONTAINS_PATH(i_conditions,'one','$.page') AND (JSON_TYPE(JSON_EXTRACT(i_conditions,'$.page'))='INTEGER' OR JSON_UNQUOTE(JSON_EXTRACT(i_conditions,'$.page')) REGEXP '[0-9]+') AND JSON_CONTAINS_PATH(i_conditions,'one','$.page_size') AND (JSON_TYPE(JSON_EXTRACT(i_conditions,'$.page_size'))='INTEGER' OR JSON_UNQUOTE(JSON_EXTRACT(i_conditions,'$.page_size')) REGEXP '[0-9]+') THEN SET @query = CONCAT(@query, ' LIMIT ', ((CAST(JSON_EXTRACT(i_conditions,'$.page') AS UNSIGNED)-1)*CAST(JSON_EXTRACT(i_conditions,'$.page_size') AS UNSIGNED)), ',', JSON_UNQUOTE(JSON_EXTRACT(i_conditions,'$.page_size'))); END IF; PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT FOUND_ROWS() INTO @row_count; SET o_result = JSON_SET(o_result, '$.return', 0, '$.row_count', @row_count); END$ DELIMITER ;