2016-06-10 4 views
0

Мы процедура, которая использует ниже While..Loop рассчитать общее количество дней и недель, уплаченную за отсутствия в нашей системе PAYROLL:Как заменить SQL While Loop с Select

EDITED

Declare @Absences Table (slno int identity (1,1),AbsenceId int, ToDate datetime) 

INSERT INTO @Absences (AbsenceID,ToDate) 
Select AbsenceID, AB.ToDate 
from t_Absence AB with (nolock) 
     Inner Join t_AbsenceCategory AB_CAT with (nolock) ON (AB.AbsenceCategoryID = AB_CAT.AbsenceCategoryID) 
where (AB_CAT.IsSSP =1) 
     and ClientID = @ClientID 
     and AB.FromDate >= @SSPYearStart --D7830 SJH 21/10/2015 
order BY AB.ToDate desc 

Declare @AbsenceID INT, @iCtr INT, @maxRows int 
Declare @FromDate datetime 

SELECT @iCtr = 1, @maxRows = MAX(slno) FROM @Absences 
Select @SSPDaysPaid = 0, @SSPweeksPaid = 0, @QualifyingDaysInWeek = 0 

If IsNull(@maxRows,0) > 0 select @FromDate = FromDate from t_Absence where AbsenceID = (SELECT AbsenceID FROM @Absences WHERE slno = 1) 

WHILE (@ictr <= @maxRows) 
    BEGIN 

     SELECT @AbsenceID = AbsenceID 
     FROM @Absences 
     WHERE slno = @iCtr 
     --Print @AbsenceID 

     If Exists (Select TOP 1 1 from t_Absence where ToDate > DATEADD(dd,-56, @FromDate)) 
      BEGIN 

       SELECT @SSPDaysPaid = @SSPDaysPaid + IsNull(A.SSPDays,0), 
        @FromDate = A.FromDate 
       from t_Absence A 
       where A.AbsenceID = @AbsenceID 

       print '@SSPDaysPaid=' + CAST(@SSPDaysPaid AS Varchar(3)) + ' in Absence ' + cast(@AbsenceID as varchar(6)) 
            DECLARE @Monday int, @Tuesday int, @Wednesday int, @Thursday int, @Friday int, @Saturday int, @Sunday int 
       SELECT @Monday = QD.Monday, @Tuesday = QD.Tuesday, @Wednesday =QD.Wednesday, @Thursday =QD.Thursday, 
         @Friday = QD.Friday, @Saturday = QD.Saturday, @Sunday = QD.Sunday 
       from t_PayrollEmployeeSSPQualifyingDays QD 
        inner JOIN t_Absence A on A.ClientID = QD.ClientID and A.FromDate = QD.DateFrom AND A.ToDate = QD.DateTo 
        where A.ClientID = @ClientId 
       SET @QualifyingDaysInWeek = @Monday + @Tuesday + @Wednesday + @Thursday + @Friday + @Saturday + @Sunday 
       print '@QualifyingDaysInWeek = ' + cast(@QualifyingDaysInWeek as char(2)) 
      END 
     SET @iCtr = @iCtr + 1 
    END 
    if @QualifyingDaysInWeek <> 0 Set @SSPWeeksPaid = @SSPDaysPaid/@QualifyingDaysInWeek Else Set @SSPWeeksPaid = 0 
    print '@SSPWeeksPaid=' + cast(@SSPWeeksPaid as varchar(2)) 
    Select 

    BradfordFactor 
    , CSPFDEntitlement 
    , CSPHDEntitlement 
    , CSPDaysTaken 
    , HasContract 
    , CSPFullDaysTaken 
    , CSPHalfDaysTaken -- DevTask 112703 06/11/2012 SWB Start 
    , IsNull(@SSPDaysPaid,0) as 'SSPDaysPaid' 
    , IsNull(@SSPWeeksPaid,0) as 'SSPWeeksPaid' 
from 
    fn_GetEmployeeBradfordFactor(@ClientID,DEFAULT,0, DEFAULT) 
END 

Как мне нужно найти эту информацию для нескольких различных лиц, я должен выполнить это хранимую процедуру и цикл один раз для каждого клиента Id (@ClientId) определен в вызывающей процедуре ...

Есть ли альтернатива этому циклу и стоит ли это с точки зрения производительности?

+1

Похоже, что ответ «нет», цикл получает информацию об отсутствии ДЛЯ КАЖДОГО клиента. Вы должны зациклиться. если вы не заботитесь о печати отсутствия на экране, а затем удалите цикл. –

+0

@ RicardoC: Ну, мне не нужны отпечатки (они там для отладки и анализа), но мне нужно суммировать значения '@ QualifyingDaysInWeek' для каждой записи в таблице' @ Absences' –

+1

Почему вы иногда используя NOLOCK и в других случаях, не используя его для той же таблицы ??? Вероятно, вам стоит ознакомиться с этим намеком, прежде чем вы поместите свою базу данных. http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –

ответ

1

на основе ОП комментария, никакого другого значения не требуется от петли, но @QualifyingDaysInWeek

@RicardoC: Ну не нужны отпечатки (они там для отладки и анализа), но Мне нужно суммировать значения @QualifyingDaysInWeek для каждой записи в таблице @Absences

Кажется, что нет необходимости в цикле вообще.

Declare @Absences Table (slno int identity (1,1),AbsenceId int, ToDate datetime) 

INSERT INTO @Absences (AbsenceID,ToDate) 
Select AbsenceID, AB.ToDate 
from t_Absence AB with (nolock) 
     Inner Join t_AbsenceCategory AB_CAT with (nolock) ON (AB.AbsenceCategoryID = AB_CAT.AbsenceCategoryID) 
where (AB_CAT.IsSSP =1) 
     and ClientID = @ClientID 
     and AB.FromDate >= @SSPYearStart --D7830 SJH 21/10/2015 
order BY AB.ToDate desc 

DECLARE @QualifyingDaysInWeek INT 

SELECT @QualifyingDaysInWeek = SUM(QD.Monday + QD.Tuesday + QD.Wednesday + QD.Thursday + QD.Friday + QD.Saturday + QD.Sunday) 
FROM t_PayrollEmployeeSSPQualifyingDays QD 
INNER JOIN t_Absence A ON A.ClientID = QD.ClientID 
          AND A.FromDate = QD.DateFrom 
          AND A.ToDate = QD.DateTo 
WHERE A.ClientID = @ClientId; 
+0

Спасибо за вашу помощь в этом, я отредактировал мое сообщение, чтобы показать результаты, которые передаются обратно вызывающему процессу ... –