2013-07-16 2 views
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 перед второй проверкой else добавьте его после предложения where.

Позже для этой процедуры может быть более двух параметров. Итак, каков наилучший способ управления этим динамическим запросом с помощью WHERE и AND?

ответ

1

Самое простое решение - просто сохранить в запросе WHERE 1=1. Оптимизатор избавится от него, и все, что вам нужно сделать, это добавить 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' 
+0

будет эта проверка влияет на процедуру ЭКСПЛУАТАЦИОННЫЕ e, если есть миллионы записей? – Ajinkya

+1

Нет оптимизатора, который избавится от него. См. Мое редактирование. –

Смежные вопросы