我剛剛創建了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?你使用什麼樣的隔離?查看查詢計劃。 –