我正在根据过滤条件编写一个从数据库表中获取记录的过程。现在用户可能会应用过滤器,也可能不会。因此,基于该过滤条件将被应用。
即。如果filter参数将包含任何值,则它将仅应用条件。
注意:我可以通过 if .. else .. condition 实现它,并分别执行不同的查询以获得我的欲望输出。但我要问的是,是否有更好的方法,而不是..其他..
示例(此处i_status_id,i_category_id可能包含任何值,也可能不包含)
DELIMITER $$
DROP PROCEDURE IF EXISTS `FilterRecord`$$
CREATE PROCEDURE `FilterRecord`(IN i_status_id BIGINT,IN i_category_id BIGINT)
BEGIN
SELECT
Item_backlog.backlog_id AS backlog_id,
Item_backlog.title AS backlog_name,
Item_backlog_Group.title AS group_Name,
Item_backlog.description AS description,
Item_backlog.est_start_date AS estimated_start_date,
Item_backlog.est_end_date AS estimated_end_date,
Item_backlog.actual_start_date AS actual_start_date,
Item_backlog.actual_end_date AS actual_end_date,
Item_backlog.estimated_hours AS estimated_hours,
Item_backlog.actual_hours AS actual_hours,
Item_backlog.status_id AS status_id,
APV_Status.name AS status_name ,
Item_backlog.priority_id AS priority_id,
APV_Priority.name AS priority_name,
Item_backlog.rank AS rank,
Item_backlog.isActive AS isActive,
Item_backlog.created_by_id AS created_by_id,
Item_backlog.created_on AS created_on,
Item_backlog.modified_by_id AS modified_by_id,
Item_backlog.modified_on AS modified_on
FROM
Item_backlog
INNER JOIN
ApplicationParamValue AS APV_Status ON (Item_backlog.status_id=APV_Status.appParamValueId)
INNER JOIN
ApplicationParamValue AS APV_Priority ON (Item_backlog.Priority_Id=APV_Priority.appParamValueId)
INNER JOIN
Item_backlog_group AS Item_backlog_Group ON (Item_backlog.backlog_group_id=Item_backlog_Group.backlog_group_id)
WHERE
Item_backlog.status_id=i_status_id
AND
Item_backlog.category_id=i_category_id
END$$
DELIMITER ;
答案 0 :(得分:0)
假设您有一个定义的值用于指示何时未指定参数(例如,我已使用下面的NULL
来指示未提供参数),您可以执行以下操作以应用有条件的参数。
CREATE PROCEDURE `FilterRecord`(IN i_status_id BIGINT,IN i_category_id BIGINT)
BEGIN
SELECT
Item_backlog.backlog_id AS backlog_id,
-- ...
FROM
Item_backlog
INNER JOIN
-- ..
WHERE
(Item_backlog.status_id=i_status_id OR i_status_id IS NULL)
AND
(Item_backlog.category_id=i_category_id OR i_category_id IS NULL);
END
但请注意,执行此操作的效果可能会降低。
SqlFiddle example here - 我假设MySql,顺便说一句,根据您的主要标记和反引号。
答案 1 :(得分:0)
尝试下面它会根据传递的参数应用过滤条件:
DELIMITER $$
DROP PROCEDURE IF EXISTS `FilterRecord`$$
CREATE PROCEDURE `FilterRecord`(IN i_status_id BIGINT,IN i_category_id BIGINT)
BEGIN
DECLARE Var_status_id VARCHAR(200);
DECLARE Var_category_id VARCHAR(200);
DECLARE andCondition VARCHAR(200);
IF i_status_id<>0 THEN
SET Var_status_id=CONCAT(' (Item_backlog.status_id = ', i_status_id,')');
SET andCondition ='AND';
ELSE
SET Var_status_id="";
SET andCondition ='';
END IF;
IF i_category_id<>0 THEN
SET Var_category_id=CONCAT(andCondition,' (Item_artifact_category_mapping.category_id = ', i_category_id,')');
ELSE
SET Var_category_id="";
END IF;
SET @SQL := CONCAT('SELECT
Item_backlog.backlog_id AS backlog_id,
Item_backlog.title AS backlog_name,
Item_backlog_Group.title AS group_Name,
Item_backlog.description AS description,
Item_backlog.est_start_date AS estimated_start_date,
Item_backlog.est_end_date AS estimated_end_date,
Item_backlog.actual_start_date AS actual_start_date,
Item_backlog.actual_end_date AS actual_end_date,
Item_backlog.estimated_hours AS estimated_hours,
Item_backlog.actual_hours AS actual_hours,
Item_backlog.status_id AS status_id,
APV_Status.name AS status_name ,
Item_backlog.priority_id AS priority_id,
APV_Priority.name AS priority_name,
Item_backlog.rank AS rank,
Item_backlog.isActive AS isActive,
Item_backlog.created_by_id AS created_by_id,
Item_backlog.created_on AS created_on,
Item_backlog.modified_by_id AS modified_by_id,
Item_backlog.modified_on AS modified_on
FROM
Item_backlog
INNER JOIN
ApplicationParamValue AS APV_Status ON (Item_backlog.status_id=APV_Status.appParamValueId)
INNER JOIN
ApplicationParamValue AS APV_Priority ON (Item_backlog.Priority_Id=APV_Priority.appParamValueId)
INNER JOIN
Item_backlog_group AS Item_backlog_Group ON (Item_backlog.backlog_group_id=Item_backlog_Group.backlog_group_id)
WHERE', Var_status_id, Var_category_id);
PREPARE stmt FROM @SQL;
EXECUTE stmt;
END$$
DELIMITER ;