【发布时间】:2020-10-01 20:50:23
【问题描述】:
我正在尝试简化以下 T-SQL 用户函数,以便在我的一个表的持久计算列中使用。我知道我可以在视图中使用计算列以及其他方法,但由于用户要求的各种原因,最好这样实现此列。
但是,为了在计算机专栏中使用此标量函数,我正在尝试使其尽可能高效和流线型。该函数的某些部分带有以下SELECT COUNT 语句
SELECT COUNT([JunctionID])
FROM dbo.ApplicationJunctionT
WHERE [AccountID] = @AccountID
AND [Outcome] IS NULL
AND [Change Account Status] IS NULL
我反复使用,我想知道是否有更好的方法来重组此功能以提高效率。我确实尝试使用 CTE 来包装这个 select 语句,但不断遇到语法问题,因此放弃了这个想法。
ALTER FUNCTION [dbo].[fnAccountReadyByID_Test]
(@JunctID INT = Null,
@AccountID VARCHAR(20) = NULL)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @FamilyAccountReady as varchar(10),
@TotalFamily as INT;
SET @TotalFamily = (SELECT COUNT([JunctionID])
FROM dbo.ApplicationJunctionT
WHERE [AccountID] = @AccountID
AND [Outcome] IS NULL
AND [Change Account Status] IS NULL)
IF @TotalFamily = 1
SET @FamilyAccountReady = (SELECT AccountStatus
FROM dbo.ApplicationJunctionT
WHERE JunctionID = @JunctID)
ELSE
SET @FamilyAccountReady = (CASE
WHEN (SELECT COUNT([JunctionID])
FROM dbo.ApplicationJunctionT
WHERE [AccountID] = @AccountID
AND [Outcome] IS NULL
AND [Change Account Status] IS NULL
AND [AccountStatus] = '-') > 0
THEN '-'
WHEN (SELECT COUNT([JunctionID])
FROM dbo.ApplicationJunctionT
WHERE [AccountID] = @AccountID
AND [Outcome] IS NULL
AND [Change Account Status] IS NULL
AND [AccountStatus] = 'Frozen') > 0
THEN 'Frozen'
WHEN (SELECT COUNT([JunctionID])
FROM dbo.ApplicationJunctionT
WHERE [AccountID] = @AccountID
AND [Outcome] IS NULL
AND [Change Account Status] IS NULL
AND [AccountStatus] = 'Closed') > 0
THEN 'Closed'
WHEN (SELECT COUNT([JunctionID])
FROM dbo.ApplicationJunctionT
WHERE [AccountID] = @AccountID
AND [Outcome] IS NULL
AND [Change Account Status] IS NULL
AND [AccountStatus] = 'Tentative') > 0
THEN 'Tentative'
ELSE 'GRANT'
END)
-- Return the result of the function
RETURN UPPER(@FamilyAccountReady)
END
此外,即使在网上阅读了多篇文章后,我也无法找到计算机栏的触发方式。更新记录中的任何字段时是否触发?还是仅在变量字段更新时触发?
在这种情况下,我使用AccountID 和JunctionID 作为变量,它们都是不变的静态字段。我的计算列在这种情况下是否仍然有效?
尽管我不喜欢效率低下,但我可能不得不采用这种设计,除非这里的专家社区可以提出一些改进建议!
非常感谢您的帮助!
【问题讨论】:
-
我认为这种方法行不通,因为您的函数是不确定的。即使使用此代码,您能否完成整个设置?
-
嗨,罗杰,还没有测试它是否有效。目前我在视图内的触发器中使用它来更新指定列,但我想删除该列并将其作为持久计算列。
-
旁白:如果不出意外,您可以用
when exists ( select 42 ... )替换重复的when ( select count ... ) > 0逻辑。无需精确计数即可与零进行比较。
标签: sql-server performance tsql user-defined-functions calculated-columns