SELECT查询使用可选的用户提供的参数过滤记录

时间:2015-04-08 10:49:47

标签: mysql sql stored-procedures

我正在根据过滤条件编写一个从数据库表中获取记录的过程。现在用户可能会应用过滤器,也可能不会。因此,基于该过滤条件将被应用。

即。如果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 ;

2 个答案:

答案 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 ;