-2

我有下面的SQL,需要1或2秒返回結果。我在光標內調用這個SQL 500次以上。我正試圖重寫這個查詢。即興SQL查詢

SELECT Sum(CASE 
       WHEN UpdatedAdjustedOT IS NOT NULL 
        AND UpdatedAdjustedOT != '' 
        AND UpdatedAdjustedOT != '0' 
        THEN CONVERT(DECIMAL(18, 2), UpdatedAdjustedOT) 
       ELSE 0 
       END) AS OTHours 
    FROM tbl_OTAuthorization 
    WHERE EmployeeCodeFK = @EmployeeCode 
     AND month(OTDate) = Month(@FromDate) 
     AND year(OTDate) = Year(@FromDate) 

請建議我以更好的方式

enter image description here

+2

那是什麼在呼喚這個外部查詢?這看起來並不昂貴,但如果您在遊標中使用它,那麼我們需要查看外部查詢以瞭解它在做什麼。 –

+0

我有工作表中的光標。我必須通過在此SQL中傳遞員工代碼來找到其他問題 – StackUser

+1

問題在於您的光標,因此發佈代碼後我們可以提供幫助 –

回答

0

首先,重新寫WHERE條款看起來像這樣:

SELECT . . . 
FROM tbl_OTAuthorization 
WHERE EmployeeCodeFK = @EmployeeCode AND 
     OTDate >= DATEADD(day, 1 - DAY(@FromDate), @FromDate) AND 
     OTDate < DATEADD(month, 1, DATEADD(@FromDate, 1 - DAY(@FromDate), @FromDate)); 

其次,創建表適當指數:

CREATE INDEX tbl_OTAuthorization_2 ON tbl_OTAuthorization(EmployeeCodeFK, OTDate, UpdatedAdjustedOT); 

第三,返回並修復您的代碼,以防止員工和日期循環。您應該能夠在單個查詢中處理邏輯。通常,如果要優化使用數據庫的性能,請避免使用遊標。

+0

謝謝Gordon Linoff – StackUser

1

不要在函數結果中過濾如何重新寫這個查詢。找到一種方法來取代這個:

AND month(OTDate) = Month(@FromDate) 
AND year(OTDate) = Year(@FromDate) 

到這樣的事情:

and OTDate >= the first day of the month for @FromDate 
and OTDate < the first day of the month following @FromDate 
0

試試這個:

SELECT Sum(CONVERT(DECIMAL(18, 2), ISNULL(NULLIF(UpdatedAdjustedOT, ''), 0))) as OTHours 
    FROM tbl_OTAuthorization 
    WHERE EmployeeCodeFK = @EmployeeCode 
     AND month(OTDate) = Month(@FromDate) 
     AND year(OTDate) = Year(@FromDate) 
0
WHERE EmployeeCodeFK = @EmployeeCode 
    AND OTDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, @FromDate), 0) 
    AND OTDate < DATEADD(MONTH, 1, DATEADD(MONTH, DATEDIFF(MONTH, 0, @FromDate), 0))