我想根据列值进行算术运算。请考虑以下示例
CREATE TABLE #test
(
cont_sal INT,
check_value INT,
operator VARCHAR(50)
)
INSERT #test
VALUES (10,20,'+'),
(20,10,'+'),
(10,20,'-'),
(20,10,'-')
预期结果:
cont_sal check_value result
-------- ----------- ------
10 20 30
20 10 30
10 20 -10
20 10 10
我可以使用CASE
语句执行此操作。
SELECT cont_sal,
check_value,
CASE
WHEN operator = '+' THEN cont_sal + check_value
when operator = '-' THEN cont_sal - check_value
END result
FROM #test
但有没有办法动态地做到这一点。运算符可以是/
,%
,*
。像这样的东西
DECLARE @sql NVARCHAR(max)=''
SET @sql = 'select cont_sal ' + 'operator'
+ ' check_value from #test '
--PRINT @sql
EXEC Sp_executesql
@sql
这显然不起作用
Msg 102,Level 15,State 1,Line 1语法不正确 'check_value'。
答案 0 :(得分:5)
好问题。
我会使用case表达式,因为:
但也有其他选择。您可以构建然后执行动态SQL语句。
-- Query will be stored here.
DECLARE @Qry VARCHAR(255) = '';
-- Build up the query.
SELECT
@Qry =
@Qry
+ CASE ROW_NUMBER() OVER (ORDER BY cont_sal)
WHEN 1 THEN 'SELECT '
ELSE 'UNION ALL SELECT '
END
+ ''''
+ Expression
+ ''''
+ ' AS Expression,'
+ Expression
+ ' AS Result '
FROM
#test AS t
CROSS APPLY
(
-- Avoid typing expression twice.
SELECT
CAST(cont_sal AS VARCHAR(50))
+ ' '
+ operator
+ ' '
+ CAST(check_value AS VARCHAR(50)) AS Expression
) AS ex
;
-- Execute it.
EXECUTE(@Qry);
或者您可以使用交叉应用来使用强力计算结果。
SELECT
*
FROM
#test AS t
CROSS APPLY
(
VALUES
('+', cont_sal + check_value),
('-', cont_sal - check_value),
('*', cont_sal * check_value),
('/', cont_sal / NULLIF(check_value, 0)),
('%', cont_sal % NULLIF(check_value, 0))
) AS ex(operator, result)
WHERE
ex.operator = t.operator
;
这里计算每个可能的操作。那些不需要的东西会从结果集中过滤掉。这种方法更易于读写,但运行从不需要的计算。也就是说,它确实生成了一个更快的查询计划,这是我的动态示例。
修改强>
感谢@Damien_The_Unbeliever,他指出我的漏洞除以零错误。我使用NULLIF将0替换为空值,这样可以避免错误。
我只更新了第二个例子。
答案 1 :(得分:1)
免责声明:我是项目的所有者Eval SQL.NET
该库允许直接在T-SQL中使用C#语法来动态计算算术表达式。运算符优先级和括号值得尊重,并且库超出了简单的数学表达式。
var message = "hello [[xxx]] bye [[ZZZ]]"
var result, re = /\[\[(.*?)\]\]/g;
while ((result = re.exec(message)) != null) {
switch (result[1].toLowerCase()) {
case "xxx":
console.log("found xxx");
break;
case "zzz":
console.log("found zzz");
break;
}
}
文档:SQL Server Eval - Dynamically evaluate arithmetic operation and expression