我刚刚创建了500万行的表。随着表结构为:
rn t1 t2 t3 formula
1 80 23 93 t1/t2 * t3
2 80 87 30 t1/t2 * t3
3 92 83 63 t1/t2 * t3
4 68 19 36 t1/t2 * t3
5 65 63 10 t1/t2 * t3
如果你确信,所有你的公式是有效的,你会不会具有例如除以零或数据类型的溢出,在这种情况下,你可以使自己的eval()函数在SQL服务器中。
我为公式中的3个值创建了我自己的函数,其符号如下: '+',' - ','*','/'。
功能码是:
use db_test;
go
alter function dbo.eval(@a varchar(max))
returns float
as
begin
set @a = replace(@a, ' ', '');
declare @pos1 int = PATINDEX('%[+/*-]%', @a);
declare @t1 float = cast(substring(@a, 1, @pos1 - 1) as float);
declare @sign1 char(1) = substring(@a, @pos1, 1);
set @a = substring(@a, @pos1 + 1, len(@a) - @pos1);
declare @pos2 int = PATINDEX('%[+/*-]%', @a);
declare @t2 float = cast(substring(@a, 1, @pos2 - 1) as float);
declare @sign2 char(1) = substring(@a, @pos2, 1);
set @a = substring(@a, @pos2 + 1, len(@a) - @pos2);
declare @t3 float = cast(@a as float);
set @t1 = (
case @sign1
when '+' then @t1 + @t2
when '-' then @t1 - @t2
when '*' then @t1 * @t2
when '/' then @t1/@t2
end
);
set @t1 = (
case @sign2
when '+' then @t1 + @t3
when '-' then @t1 - @t3
when '*' then @t1 * @t3
when '/' then @t1/@t3
end
);
return @t1;
end;
而且它适用于下一个数据:
select dbo.eval('7.6*11.3/4.5') as eval, 7.6*11.3/4.5 as sqlServerCalc;
eval sqlServerCalc
19,0844444444444 19.084444
后,您可以通过列值的公式中替换值,并计算出它:
with cte as (
select rn, t1, t2, t3, formula,
REPLACE(REPLACE(REPLACE(formula, 't1', cast(t1 as varchar(max))), 't2', cast(t2 as varchar(max))), 't3', cast(t3 as varchar(max))) as calc
from db_test.dbo.loop
)
select rn, t1, t2, t3, formula, db_test.dbo.eval(calc) as result
into db_test.dbo.loop2
from cte;
时间对我来说没问题,我的Sql Server 2016需要3分钟,并且效果很好:
select top 5 *
from db_test.dbo.loop2;
rn t1 t2 t3 formula result
1 80 23 93 t1/t2 * t3 323,478260869565
2 80 87 30 t1/t2 * t3 27,5862068965517
3 92 83 63 t1/t2 * t3 69,8313253012048
4 68 19 36 t1/t2 * t3 128,842105263158
5 65 63 10 t1/t2 * t3 10,3174603174603
如果您有公式中适用的所有操作的列表,则可以为多个变量编写一个通用函数。但是,如果公式中有更复杂的部分,那么应该使用CLR。
您可能想在[代码评论](https://codereview.stackexchange.com/)上发布此信息。这是工作代码更好的地方,你想加快速度。 –
是公式行为计算列吗? –
您需要在'update'中寻找瓶颈。你有任何触发器,索引或FK?你使用什么样的隔离?查看查询计划。 –