2

这是我的MySQL程序

DELIMITER $$

DROP PROCEDURE IF EXISTS `awaredb2`.`GetAlertList`$$

CREATE DEFINER=`aware`@`%` PROCEDURE `GetAlertList`(IN deviceIds VARCHAR(200), IN appIds VARCHAR(30000))
BEGIN


        SET @QUERY = '  SELECT P.policy_id AS PolicyId,
                        P.name AS PolicyName,
                        (MAX(A.alert_create_date)) AS AlertCreateDate, ';

        IF deviceIds != ''
        THEN
            SET @QUERY = CONCAT(@QUERY, '   SUM(AR.penalty) AS Penalty, ');
        ELSE
            SET @QUERY = CONCAT(@QUERY, '   '''' AS Penalty, ');
        END IF;

        SET @QUERY = CONCAT(@QUERY,'    A.device_id AS DeviceId
                    FROM alert A
                        JOIN alert_rule AR ON AR.alert_id = A.id
                        JOIN policy P ON P.id = A.policy_id 
                        JOIN device D ON D.id = A.device_id
                    WHERE P.name != '''' ');

        IF deviceIds != ''
        THEN
            SET @QUERY = CONCAT(@QUERY, ' AND A.device_id IN(', deviceIds, ') ');
        END IF;
        -- 
        IF appIds != ''
        THEN
            SET @QUERY = CONCAT(@QUERY, ' AND A.app_id IN(', appIds, ') ');
        END IF;


        SET @QUERY = CONCAT(@QUERY, '   GROUP BY P.name
                        ORDER BY AlertCreateDate DESC ');
        PREPARE stmt FROM @QUERY;
        EXECUTE stmt;
        SELECT @QUERY;
    END$$

DELIMITER ;

此过程接受两个参数。如果参数值不为空,则该值将用于准备 sql 语句并最终执行。

现在我被要求删除第一个默认条件P.name != ''。如果我每次都删除这个条件,我将不得不检查其他两个参数是否存在。如果存在,则添加 where 子句。如果两者都存在,则AND在第二次检查之前添加,否则在 where 子句之后添加。

稍后,此过程可能有两个以上的参数。那么使用WHEREand管理这个动态查询的最佳方法是什么AND

4

1 回答 1

1

最简单的解决方案就是WHERE 1=1在查询中保留 a 。优化器将摆脱它,您所要做的就是添加AND ...块。

另请参阅http://dev.mysql.com/doc/internals/en/optimizer-primary-optimizations.html,第 8.2.1.2 节:

对于始终为真的条件会发生转换,例如:

WHERE 0=0 AND column1='y'

在这种情况下,第一个条件被删除,留下

WHERE column1='y'
于 2013-07-16T09:30:09.277 回答