使用TSQL根据映射计算规则为NewCode赋值的技术求助
解决SSMS中根据Mapping规则计算NewCode值的问题
嗨,我来帮你搞定这个在SSMS里计算NewCode对应值的需求!首先咱们先理清楚核心任务:把NewCodes表Mapping列里的加减表达式,替换成Source Codes表中对应Code的数值,然后算出最终结果对吧?
先处理格式问题(必做!)
首先得先修正你NewCodes表里的两处格式错误,不然后续计算肯定会报错:
ww1的Mapping:[RE5] + RE6] + [RE7]→ 改成[RE5] + [RE6] + [RE7](补全RE6的左括号)zx1的Mapping:[KJ1] – [XC4]→ 改成[KJ1] - [XC4](把中文破折号换成英文减号)
另外,zx1里的KJ1和XC4目前不在Source Codes表里,要么补充这两个Code的数值,要么调整Mapping,否则计算时会提示找不到对应的Code值。
方法1:用自定义函数批量计算(推荐,灵活易用)
我们可以创建一个自定义标量函数,用来解析单个Mapping表达式并计算结果,之后直接用这个函数查询即可:
第一步:创建计算函数
CREATE FUNCTION dbo.GetCalculatedValue (@Mapping NVARCHAR(200)) RETURNS INT AS BEGIN DECLARE @ProcessedExpr NVARCHAR(200) = @Mapping DECLARE @Result INT -- 把表达式里的[Code]全部替换成对应的数值 SELECT @ProcessedExpr = REPLACE(@ProcessedExpr, '[' + Code + ']', CAST(Value AS VARCHAR(20))) FROM [Source Codes] -- 执行表达式计算 DECLARE @SQL NVARCHAR(MAX) = N'SELECT @CalculatedResult = ' + @ProcessedExpr EXEC sp_executesql @SQL, N'@CalculatedResult INT OUTPUT', @CalculatedResult = @Result OUTPUT RETURN @Result END
第二步:使用函数查询结果
SELECT NewCode, Mapping, dbo.GetCalculatedValue(Mapping) AS CalculatedValue FROM NewCodes
执行这段SQL后,你就能看到每个NewCode对应的计算结果了:
- pp1:35+10=45
- qq1:20-5=15
- ww1:7+8+6=21
- zx1:如果补充了KJ1和XC4的数值,就能算出对应结果
方法2:用动态SQL一次性生成结果(适合批量写入或一次性处理)
如果你需要把结果直接写入新表或者批量处理,动态SQL会更高效:
-- 创建临时表存储结果 CREATE TABLE #FinalResults ( NewCode VARCHAR(10), CalculatedValue INT ) DECLARE @DynamicSQL NVARCHAR(MAX) = '' -- 生成每个NewCode的计算语句 SELECT @DynamicSQL = @DynamicSQL + N' INSERT INTO #FinalResults (NewCode, CalculatedValue) SELECT ''' + NewCode + ''', ' + -- 替换当前Mapping里的所有Code为对应数值 (SELECT STRING_AGG(REPLACE(nc.Mapping, '[' + sc.Code + ']', CAST(sc.Value AS VARCHAR(10))), '') FROM [Source Codes] sc WHERE CHARINDEX('[' + sc.Code + ']', nc.Mapping) > 0) + ' ' FROM NewCodes nc -- 执行动态SQL EXEC sp_executesql @DynamicSQL -- 查询结果 SELECT * FROM #FinalResults -- 清理临时表 DROP TABLE #FinalResults
注意事项
- 权限问题:执行动态SQL或自定义函数里的
sp_executesql需要当前用户有对应的执行权限,如果遇到权限报错,可以联系DBA调整权限。 - 数据类型:如果
Source Codes里的Value是小数类型,需要把函数和SQL里的INT改成DECIMAL或FLOAT,避免精度丢失。 - 异常处理:如果Mapping里有无效的表达式(比如除零、不存在的Code),会触发报错,你可以在函数里添加TRY-CATCH块来捕获异常,返回NULL或自定义提示。
内容的提问来源于stack exchange,提问作者Humza Yusuf
相关产品推荐
相关产品推荐

