需求:用戶下機時自動計算上機時長並轉換為費用,寫入上機記錄表。使用 SQL Server 觸發器實現。
CREATE TABLE SessionLog (
SessionID int PRIMARY KEY,
UserID int,
LoginTime datetime,
LogoutTime datetime,
DurationMinutes int, -- 計算得出
Fee decimal(10,2) -- 計算得出
);
SQL Server 中 datetime 可直接相減得到 datetime 差值 (以天為單位),再轉換:
-- 1. 相減得到天數差 (含小數)
DECLARE @diffDays float = DATEDIFF(second, @LoginTime, @LogoutTime) / 86400.0;
-- 2. 轉分鐘
DECLARE @minutes int = ROUND(@diffDays * 24 * 60, 0);
-- 3. 計算費用 (例: 5元/小時,不足小時按半小時計)
DECLARE @hours float = @minutes / 60.0;
DECLARE @fee decimal(10,2) = ROUND(CEILING(@hours * 2) / 2.0 * 5, 2);
CREATE TRIGGER trg_CalcFee_OnLogout
ON SessionLog
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- 僅處理 LogoutTime 從 NULL 變為非 NULL 的行
UPDATE s
SET
DurationMinutes = DATEDIFF(MINUTE, i.LoginTime, i.LogoutTime),
Fee = ROUND(CEILING(DATEDIFF(MINUTE, i.LoginTime, i.LogoutTime) / 60.0 * 2) / 2.0 * 5, 2)
FROM SessionLog s
INNER JOIN inserted i ON s.SessionID = i.SessionID
INNER JOIN deleted d ON s.SessionID = d.SessionID
WHERE d.LogoutTime IS NULL AND i.LogoutTime IS NOT NULL;
END;
DATEDIFF(MINUTE, start, end) 直接得到分鐘差,避免浮點轉換誤差。inserted/deleted 虛擬表捕獲更新前後值,精準判斷「下機」動作。CEILING(小時數 * 2) / 2.0 實現「不足半小時按半小時計」。SET NOCOUNT ON 減少網絡開銷。-- 假設 夜間(22:00-08:00) 半價
DECLARE @totalMinutes = DATEDIFF(MINUTE, @LoginTime, @LogoutTime);
DECLARE @nightMinutes = 0;
-- 這裡需循環或使用數字表計算夜間分鐘數,略
DECLARE @fee = (@totalMinutes - @nightMinutes) * 5/60.0 + @nightMinutes * 2.5/60.0;
觸發器自動計費,應用層無需關心計算邏輯,保證數據一致性。