Мне нужно было разработать запланированную работу, которая будет выполняться ежедневно по ночам.Я выполнил задачу, но мне пришлось использовать цикл «Пока».Что заставляет меня чувствовать себя "виноватым".Мне нужны некоторые советы о том, как преобразовать эту операцию в операцию на основе набора и повысить производительность.
Моя таблица выглядит (максимально упрощенной):
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)