Избежание во время цикла в T-SQL - PullRequest
2 голосов
/ 18 ноября 2011

Мне нужно было разработать запланированную работу, которая будет выполняться ежедневно по ночам.Я выполнил задачу, но мне пришлось использовать цикл «Пока».Что заставляет меня чувствовать себя "виноватым".Мне нужны некоторые советы о том, как преобразовать эту операцию в операцию на основе набора и повысить производительность.

Моя таблица выглядит (максимально упрощенной):

T_POOL
PoolID | ContactID | ContactState
  1    |     1     |      1
  1    |     2     |      1
  1    |     3     |      1
  2    |     4     |      2
  2    |     5     |      3

 T_POOL_DEC
 PoolID | Layer4ID
   1    |    1
   2    |    3
   3    |    5

 T_LAYER4
 Layer4ID | ConditionValue1(Count) | ConditionValue2(Month)
    1     |       5                | 3

Причина, по которой я использовал цикл while, заключается в получении значений ContactID (в виде группы) относительно PoolID.Хранение различных значений poolID во временной таблице и извлечение этих значений poolID в цикле. Так что в то время как цикл While Loop выполняет циклическое переключение между различными значениями PoolID (не просматривая все таблицы построчно), и я выполняю операции обновления, которыеможет быть продемонстрировано как:

  While (True)
    Take Next @PoolID

    Update T_Pool TP SET ContactState ={some value} 
    INNER JOIN T_POOL_DEC PD ON PD.PoolID = TP.PoolID
    INNER JOIN T_LAYER4 L4 ON L4.Layer4ID = PD.Layer4ID
    Where {COUNT(TP.ContactID) >= L4.ConditionValue1 
    AND ContactID.CreateDate >=DATEADD(MM,L4.ConditionValue2*-1,GETDATE()}
    AND PoolID = @PoolID

    If it has passed through all available PoolIDs, break;
  END

Я надеюсь, что смогу продемонстрировать ситуацию настолько ясно, насколько это возможно, так как я не могу написать весь запрос здесь.

Редактировать для комментариев: Забыл добавить, что, что мешает мне обновить всю таблицу, так это PoolID выше FK.И у каждого PoolID есть Layer4ID, я делаю некоторые вычисления для каждого ContactID в пуле в зависимости от значений Layer4 этого PoolID (например, подсчет каждого контакта в пуле в зависимости от их состояния и проверка, равен ли результат подсчета или больше, чемего значение в пуле Layer4. Редактирование демонстрационной части моей таблицы для большей ясности.

Итак, как видно выше, у каждого пула есть Layer4ID. И у каждого Layer4 есть некоторые условия, в этом случае оба являются целыми числами (ConditionValue1 указывает минимальное количество идентификаторов ContactID, которые должны быть обновлены (я имею в виду обновление состояния в таблице T_POOL), а ConditionValue2 указывает количество месяцев после текущей даты для каждого контакта, который будет считаться действительным (для обновления его состояния).дата из собственной таблицы .-

Edit2 Добавлены некоторые объединения в мой пример запроса (игнорировать синтаксическую ошибку, группировать по и т. д.)

Edit3

Мой текущий запрос может выглядеть следующим образом: так просто, это должно быть "бесплатно"d "из цикла while, а именно исключение использования @PoolID.

UPDATE T_POOL SET ContactState= 4
WHERE PoolID= @PoolID AND ContactState=2
AND EXISTS(
SELECT T.ContactID FROM(
   SELECT TP.ContactID,
      L4.ConditionValue1,
      COUNT(TP.ContactID) OVER (PARTITION BY TP.PoolID) AS TOTAL_CONTACT_COUNT
   FROM Contact C
   INNER JOIN T_POOL TP ON TP.ContactID= C.ContactID
   INNER JOIN T_POOL_DEC PD ON PD.PoolID = TP.PoolID
       INNER JOIN T_LAYER4 L4 ON L4.Layer4ID = PD.Layer4ID
   WHERE PD.PoolID= @PoolID AND TP.State=2 AND TP.LOG_STATUS NOT IN (9,10) AND  C.LOG_CREATE_DATE >= DATEADD(MM,L4.ConditionValue2*-1,GETDATE()))T 

 WHERE T.TOTAL_CONTACT_COUNT>=T.ConditionValue1 AND C.ContactID= ContactID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...