SQL Server 2012:基于三列优先级填充Country字段的函数问题求助
解决SQL Server 2012中按优先级填充Country字段的函数问题
嘿,我懂你要实现的逻辑啦——按country、city、office的优先级来推导最终的Country值,还得处理首字母大写的要求。虽然你没贴出之前出错的代码,但我可以给你一套符合需求的完整实现方案,咱们一步步来拆解:
核心逻辑回顾
- 优先级1:如果
country列非空且不是空白字符串,将其转为首字母大写格式 - 优先级2:如果
country为空/空白,根据city列匹配对应的国家 - 优先级3:如果前两列都为空/空白,根据
office列推导对应的国家 - 兜底:所有列都为空时返回
NULL(你也可以改成自定义默认值)
完整函数实现
1. 先创建辅助函数(处理首字母大写,可选)
如果你需要每个单词首字母大写(比如"new york"转"New York"),可以先创建这个辅助函数:
CREATE FUNCTION dbo.ProperCase ( @InputString NVARCHAR(MAX) ) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @Result NVARCHAR(MAX) = '' DECLARE @CurrentChar CHAR(1) DECLARE @Index INT = 1 -- 先转全小写并去除前后空格 SET @InputString = LTRIM(RTRIM(LOWER(@InputString))) WHILE @Index <= LEN(@InputString) BEGIN SET @CurrentChar = SUBSTRING(@InputString, @Index, 1) -- 第一个字符或者空格/连字符/下划线后的字符转大写 IF @Index = 1 OR SUBSTRING(@InputString, @Index - 1, 1) IN (' ', '-', '_') SET @Result = @Result + UPPER(@CurrentChar) ELSE SET @Result = @Result + @CurrentChar SET @Index = @Index + 1 END RETURN @Result END GO
2. 主函数实现(按优先级计算Country)
假设你有两张映射表:CityCountryLookup(存储城市与国家的对应关系,包含City和Country字段)、OfficeCountryLookup(存储办公地点与国家的对应关系,包含Office和Country字段)。如果你的映射是硬编码的,直接替换成CASE WHEN语句即可:
CREATE FUNCTION dbo.GetCountryByPriority ( @Country NVARCHAR(100), @City NVARCHAR(100), @Office NVARCHAR(100) ) RETURNS NVARCHAR(100) AS BEGIN DECLARE @Result NVARCHAR(100) -- 第一步:优先处理非空的country列 IF LTRIM(RTRIM(ISNULL(@Country, ''))) <> '' BEGIN -- 如果你只需要整个字符串首字母大写,用下面这行: -- SET @Result = STUFF(LOWER(LTRIM(RTRIM(@Country))), 1, 1, UPPER(LEFT(LTRIM(RTRIM(@Country)), 1))) -- 如果需要每个单词首字母大写,调用上面的辅助函数: SET @Result = dbo.ProperCase(LTRIM(RTRIM(@Country))) END -- 第二步:country为空时,通过city匹配国家 ELSE IF LTRIM(RTRIM(ISNULL(@City, ''))) <> '' BEGIN SELECT @Result = Country FROM dbo.CityCountryLookup WHERE LTRIM(RTRIM(City)) = LTRIM(RTRIM(@City)) -- 如果找不到匹配的城市,返回NULL(可自定义默认值) IF @Result IS NULL SET @Result = NULL END -- 第三步:前两列都为空时,通过office匹配国家 ELSE IF LTRIM(RTRIM(ISNULL(@Office, ''))) <> '' BEGIN SELECT @Result = Country FROM dbo.OfficeCountryLookup WHERE LTRIM(RTRIM(Office)) = LTRIM(RTRIM(@Office)) -- 找不到匹配的办公地点时返回NULL(可自定义默认值) IF @Result IS NULL SET @Result = NULL END -- 所有列都为空的情况 ELSE SET @Result = NULL RETURN @Result END GO
使用示例
你可以在查询中直接调用这个函数:
SELECT OriginalCountry = Country, City, Office, CalculatedCountry = dbo.GetCountryByPriority(Country, City, Office) FROM YourTargetTableName
可能的错误排查点
如果之前的代码没得到正确结果,大概率是这几个原因:
- 没处理空白字符串:只判断了
@Country IS NULL,没考虑@Country = ''或者@Country = ' '的情况,用LTRIM(RTRIM(ISNULL(@Country, ''))) <> ''才能覆盖所有空值/空白场景 - 首字母大写处理有误:比如直接用
UPPER(LEFT(@Country,1)) + RIGHT(@Country, LEN(@Country)-1),没处理原字符串的小写部分,导致结果混乱 - 匹配city/office时没去除前后空格:比如城市存储的是
'London',但传入的是' London ',没Trim就会匹配失败 - 没处理找不到映射的情况:比如某个城市不在映射表中,直接返回了
NULL但你没意识到,或者没设置默认值
内容的提问来源于stack exchange,提问作者LearnerBee
相关产品推荐
相关产品推荐

