新人开发,求提供思路

就爱灬爆炸头 发布于 2014/10/21 10:23
阅读 340
收藏 0

计算3000条记录,每一条记录有个【扣款单价】字段是要计算出来的。

计算单价的时候,要去各个表,取数据。大概要取【26个值】。

为了减少数据库访问次数,现思路如下:

主要分4个存储过程

存储过程【A】:专门用来计算单价(其中用do while 遍历3000条记录,每次选择【没有扣款单价】的最小id),同时这个存储过程调用存储过程【B】【C】,也就是【B】【C】要调用3000次。

存储过程【B】:专门用来计算成本单价(分成不同的【类型】,例如外球笼,內球笼,轴杆,进行取值)

存储过程【C】:计算加工工价,循环执行【存储过程D】(也就是一条工艺路线上,各个工序单价的和)

存储过程【D】:查找单个工序的单价

现情况如下:

3000条记录每一条计算1秒。3000条就是3000秒。

我想换种思路,领导也要求,3000条计算大概1-2分钟内完成。

在部分数据表格,非常庞大的前提下,有没有富有经验的人提供些好的思路。

我真的感激不尽。在入门阶段,大家都很忙,新人处处碰壁,没人指导。

希望有大神提供新的思路!






我说个简单的例子


主表【A】,三个字段a1,a2,a3


a3是最后要的【扣款单价】,且a3=a1+a2


a1来自表【B】【C】【D】经过各种判断而来


a2来自表【E】【F】经过各种判断而来


现在要计算表【A】的3000条记录。


怎么实现一次性查出来,以及批量保存。能稍微写点吗。感激不尽了。


例如a1是【循环工价】--也就是各个工序的和

代码如下:

ALTER PROCEDURE [dbo].[sp_kkCalculateJggj]


@jggx nvarchar(50),
@cpmc nvarchar(50),
@lskbh nvarchar(50),
@nfbh nvarchar(50),
@value decimal(18,3) output


AS
declare
@i int, --循环变量
@jgdj decimal(18,3),
@jggj decimal(18,3),
@Finterid int,
@Fentryid int


set @jgdj=0
set @jggj=0
set @i=1
select top 1 @Fentryid=Fentryid,@Finterid=Finterid from gspscb.dbo.cp_gxdj 
where cpmc=@cpmc and jggx=@jggx


WHILE @i<=@Fentryid
BEGIN
select @jggx=jggx  from gspscb.dbo.cp_gxdj 
where Finterid=@Finterid and Fentryid=@i and cpmc=@cpmc
--获得单个工序单价
exec [sp_kkCalculateJgdj_new] @jggx,@cpmc,@lskbh,@nfbh,@jgdj output
set @jggj=@jggj+@jgdj
set @i=@i+1
END


set @value=@jggj

单个工序单价的代码如下

ALTER PROCEDURE [dbo].[sp_kkCalculateJgdj_new]
@jggx nvarchar(50),
@cpmc nvarchar(50),
@lskbh nvarchar(50),
@nfbh nvarchar(50),
@jgdj decimal(18,3) output --输出jgdj
AS
declare
@id int,
@devicename nvarchar(50),
@vtx nvarchar(50),
@ftx nvarchar(50),
@ballsize nvarchar(50),
@ftype nvarchar(50),
@rclcd decimal(18,3),
@jgdw nvarchar(20)


--如果有淬火工序
if(charindex('淬火',@jggx) > 0)
begin
select top(1) @ftype=ftype,@rclcd=rclcd from gspscb.dbo.s_cprclcd where cpmc=@cpmc and jggx= @jggx
select top(1)@jgdj=rcldj FROM gspscb.dbo.s_rcldj where ftype=@ftype and @rclcd between fminlength and fmaxlength order by Fsdate desc
end
else
begin
--搜索流水卡信息
SELECT top 1 @id=t1.worktaskid,@devicename=isnull(t1.devicename,''),@vtx=isnull(t1.vtx,''),@ftx=isnull(t1.ftx,''),@ballsize=isnull(t1.ballsize,'') FROM task.dbo.t_worktask t1 LEFT OUTER JOIN task.dbo.t_order t2 ON t1.produceplanno = t2.orderid WHERE t2.wastecardno=@lskbh and t2.year=@nfbh and t1.workprocedurename=@jggx
--如果有流水卡编号
if(@id is not null)
begin
select top 1 @jgdj=unitprice from task.dbo.t_workprice where workprocedurename=@jggx and isnull(devicename,'')=@devicename and isnull(vtx,'')=@vtx and isnull(ftx,'')=@ftx and isnull(ballsize,'')=@ballsize order by begindate desc
end
--如果没有流水卡编号
else
begin
select @jgdj=max(unitprice) from task.dbo.t_workprice where workprocedurename=@jggx
end
end
if(@jgdj is null)
begin
select top(1) @jgdj=jgdj,@jgdw=jgdw from gspscb.dbo.S_CPGXDJK_wx where jggx=@jggx and cpmc =@cpmc order by fsdate desc
if(@jgdw='热处理部')
begin
set @rclcd=@jgdj
set @jgdj=null
select top(1) @ftype=ftype from gspscb.dbo.s_cprclcd where cpmc=@cpmc
select top(1)@jgdj=rcldj FROM gspscb.dbo.s_rcldj where ftype=@ftype and @rclcd between fminlength and fmaxlength order by Fsdate desc
end
end
if(@jgdj is null)
begin
set @jgdj=0
insert into koukuan.dbo.no_jgdj select @cpmc,@jggx,@lskbh,@nfbh
end


加载中
0
大连馋师
大连馋师

建议方法一:
a1来自表【B】【C】【D】经过各种判断而来
a2来自表【E】【F】经过各种判断而来
-----------------------------------------------------------------------------------------------
在表BCDEF 生成记录的同时,冗余存储一些判断信息到A表(建议存储过程,不建议使用触发器)!这样的话,计算的时候只需要A这一张表即可!


方法二:
代码直接控制ABCDEF,同时读取到内存中,采用合理的数据结构存储,如数组、链表、map、set都行,在代码中直接计算A表,把计算结果存入数据库。


最后,根据你的场景优化方法一和二。

就爱灬爆炸头
就爱灬爆炸头
谢谢提供思路!
0
Kingviker
Kingviker
为什么要用存储过程,数据一次性都查出来 用代码去计算 然后在批量保存 你的存储过程每次计算都要查表 所以慢
就爱灬爆炸头
就爱灬爆炸头
我说个简单的例子 主表【A】,三个字段a1,a2,a3 a3是最后要的【扣款单价】,且a3=a1+a2 a1来自表【B】【C】【D】经过各种判断而来 a2来自表【E】【F】经过各种判断而来 现在要计算表【A】的3000条记录。 怎么实现一次性查出来,以及批量保存。能稍微写点吗。感激不尽了。
0
大连馋师
大连馋师
贴出你的表结构、数据量、性能要求。 总体来说,计算3000条记录,无论是SQL还是代码都是小菜一碟。要有信心。
就爱灬爆炸头
就爱灬爆炸头
你好,我已经把代码放上来了。您看看,有没有什么好的方法。真的感谢了
返回顶部
顶部