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 ;

このプロシージャは、2 つのパラメータを受け入れます。パラメータ値が空でない場合、SQL ステートメントを準備して最後に実行するためにその値が使用されます。

ここで、最初のデフォルト条件を削除するよう求められますP.name != ''。毎回この条件を削除すると、他の 2 つのパラメーターが存在するかどうかを確認する必要があります。存在する場合は、where 句を追加します。両方が存在する場合は、AND2 番目のチェックの前に追加します。それ以外の場合は、where 句の後に追加します。

後で、このプロシージャーに 3 つ以上のパラメーターが存在する可能性があります。WHEREでは、この動的クエリをandで管理する最良の方法は何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も参照してください。

変換は、常に true である条件に対して行われます。たとえば、次のようになります。

WHERE 0=0 AND column1='y'

この場合、最初の条件が削除され、

WHERE column1='y'
于 2013-07-16T09:30:09.277 に答える