我有这样的场景,其中可以为存储过程提供可选的参数值。如果值为空/默认值,我希望保留现有值。
以下用CASE语句处理它的方法正确吗?这对我有效,但有更好的方法吗?
CREATE PROCEDURE [UpdateUser]
(
@UserID int,
@UserKey VARCHAR(32),
@UserName varchar(50),
@CategoryID INT = 0,
)
AS
BEGIN
SET NOCOUNT ON
UPDATE [Users]
SET
[UserKey] = (CASE WHEN (LEN(RTRIM(LTRIM(@UserKey)))>0) THEN @UserKey ELSE UserKey END )
,[UserName] = (CASE WHEN (LEN(RTRIM(LTRIM(@UserName)))>0) THEN @UserName ELSE UserName END )
,[CategoryID] = (CASE WHEN (@CategoryID>0) THEN @CategoryID ELSE CategoryID END )
WHERE
[UserID] = @UserID
END
一种"更好"(就语法简单性而言)的方法是使用NULLIF()
和ISNULL
/COALESCE
,而不是CASE表达式:
UPDATE [Users]
SET
UserKey = COALESCE(NULLIF(@UserKey , ''), UserKey ),
UserName = COALESCE(NULLIF(@UserName , ''), UserName ),
CategoryID = COALESCE(NULLIF(@CategoryID, 0 ), CategoryID)
WHERE
UserID = @UserID
;
为了解释缺少LTRIM()
和RTRIM()
的原因,在Transact-SQL中的字符串比较中将忽略尾随空格。这意味着一个(任意数量)空格的字符串将与另一个(任何其他数量)空格字符串以及一个空字符串相匹配。(因此,LEN()
函数在计算字符串长度时也会忽略尾部空格,因此,例如,LEN(SPACE(10))
将返回0而不是10。)