游標處理逐列邏輯效能差、程式碼複雜。SQL Server 2000 支援純量函數與 `SUM(expression)` 彈性,可將計算邏輯封裝於函數,在集合式查詢中呼叫,大幅簡化程式碼並提升效能。
情境:更新表 A 的欄位,需依據表 B、C 的關聯資料計算。
CREATE FUNCTION dbo.FUN_GETTIME (@TASKPHASEID INT)
RETURNS FLOAT AS
BEGIN
DECLARE @TASKID INT, @HOUR FLOAT, @PERCENT FLOAT, @RETURN FLOAT
IF @TASKPHASEID IS NULL RETURN 0.0
SELECT @TASKID = TASKID, @PERCENT = ISNULL(WORKPERCENT,0)/100
FROM TABLETASKPHASE WHERE TASKPHASEID = @TASKPHASEID
SELECT @HOUR = ISNULL(TASKTIME,0) FROM TABLETASK WHERE TASKID = @TASKID
SET @RETURN = @HOUR * @PERCENT
RETURN @RETURN
END
UPDATE TABLEFMECA SET Cvalue_M = ISNULL(MODERATE,0) * ISNULL(FMERATE,0) * ISNULL(B.BASFAILURERATE,0) * dbo.FUN_GETTIME(C.ID) FROM TABLEFMECA JOIN TABLERELATION B ON ... JOIN TABLETASKPHASE C ON ... WHERE ...
優點:避免游標迴圈、SQL 最佳化器可產生集合式執行計畫、程式碼可讀性高。
情境:依多重條件查找費率,再乘以數量彙總,無法預存中間值。
CREATE FUNCTION dbo.FUN_RATE (
@PARTID INT, @ENID INT, @SOURCEID INT, @QUALITYID INT, @COUNT INT
) RETURNS FLOAT AS
BEGIN
DECLARE @QXS FLOAT, @G FLOAT, @RATE FLOAT
IF @ENID IS NULL OR @PARTID IS NULL OR @SOURCEID IS NULL OR @QUALITYID IS NULL
RETURN 0.0
SELECT @QXS = ISNULL(XS,0)
FROM TABLEQUALITY
WHERE PARTID = @PARTID AND ENID = @ENID AND SOURCEID = @SOURCEID
AND QUALITYID = @QUALITYID
AND ( (MINCOUNT <= @COUNT AND MAXCOUNT >= @COUNT) OR (@COUNT > MAXCOUNT) )
-- 後續計算邏輯...
RETURN @RATE
END
SELECT SUM(dbo.FUN_RATE(PARTID, ENID, SOURCEID, QUALITYID, QTY)) FROM TRANSACTION_TABLE WHERE ...
關鍵點:`SUM()` 的 `expression` 參數接受函數呼叫,將逐列計算邏輯封裝於函數,主查詢保持集合式風格。