欢迎光临
我们一直在努力

一个自认为写得还可以的存储过程,就是没有注释,看起来有点乱。与ERP的BOM相关的-.NET教程,Asp.Net开发

建站超值云服务器,限时71元/月

图示如下:所使用数据库 : sql server 2000,数据表名:te(乱七八糟命名的)表结构: varchar(20) varchar(20) decimal(20,4) assbompoint sl  产成品半成品12  产成品半成品2 3  产成品半成品3 2  半成品1半成品4 2  半成品1半成品5 2  半成品3半成品5 3   

最终需要输出结果

 assbompoint sl  产成品 半成品23  产成品 半成品44 产成品 半成品513 

即一单位产成品需要底级半成品的数量以及半成品的名称。比如说半成品4=1单位产成品*2单位半成品1*2单位半成品4。

存储过程如下:(呵呵,命名就别讲究了,我没有太过于留意)

create procedure getbomtruelist
 @assbomname varchar(20),@pointname varchar(20),@expre varchar(500)
as
begin
 declare @sl decimal(20,4)
 declare @expression varchar(500)
 declare @point varchar(20)

 declare @bomtop varchar(20)
 declare #point_cursor cursor local for
  select distinct point,sl from te where assbom  = @pointname
 open #point_cursor

 fetch next from #point_cursor
  into @point,@sl

 while @@fetch_status = 0
 begin
  –如果没有下级节点了,就加入到数据表中
  if(exists(select point from te where assbom = @point))
  begin
   –如果有下级节点,则再次循环
   select @expression = rtrim(@expre) + * + rtrim(convert(char(25),@sl))
   exec(getbomtruelist + @assbomname + , + @point + ," + @expression + ")
  end
  else
  begin
   insert into #bomtemp values (@assbomname,@point,@sl,@expre + * + ltrim(rtrim(convert(char(25),@sl))))
  end
  
  fetch next from #point_cursor
   into @point,@sl
 end

 close #point_cursor
 deallocate #point_cursor
end
go

——————————————————————————————————-

create procedure getbomlist
as

begin

 create table #bomtemp (assbom varchar(20),point varchar(20),sl decimal(20,4),expression varchar(500))
 create table #bomlast (assbom varchar(20),point varchar(20),sl decimal(20,4))

 –调用递归
 declare @bomtop varchar(20)
 declare bom_cursor cursor for
  select distinct assbom from te where assbom not in (select point from te)

 open bom_cursor

 fetch next from bom_cursor
  into @bomtop

 while @@fetch_status = 0
 begin
  exec(getbomtruelist + @bomtop +,+@bomtop+,+1)

  fetch next from bom_cursor
   into @bomtop
 end

 close bom_cursor
 deallocate bom_cursor

 –获得到数据及运算表达式后,再次利用数据表中的表达式运算一下
 declare @assbomt varchar(20)
 declare @point varchar(20)
 declare @expression varchar(500)
 declare @value decimal(20,4)

 declare @execupdate varchar(500)

 declare bom_cursor_end cursor for
  select assbom,point,expression from #bomtemp
 open bom_cursor_end
 fetch next from bom_cursor_end
  into @assbomt,@point,@expression
 while @@fetch_status = 0
 begin
  set @execupdate = insert into #bomlast values( + char(39) + rtrim(@assbomt) + char(39) + , + char(39) + rtrim(@point) + char(39) + , + rtrim(@expression) + )
  –set @execupdate = update #bomtemp set sl = + rtrim(@expression) + where assbom = + char(39) + rtrim(@assbomt) + char(39) + and point = + char(39) + rtrim(@point) + char(39)
  exec(@execupdate)
  fetch next from bom_cursor_end
   into @assbomt,@point,@expression
 end

 close bom_cursor_end
 deallocate bom_cursor_end

 select assbom,point,sum(sl) as sl from #bomlast group by assbom,point

 drop table #bomtemp
 drop table #bomlast
end

————————————————————————-

设计思路:

首先第一步就是得到顶级的产成品,由于在测试的表中有多个产成品,因此需要对顶级的产成品加一个游标,一行行处理。

得到一个产成品后,再去获取其下级的半成品,并且得到需要的半成品数量,将其数量先设成一个表达式,如1*3,如果半成品还有半成品,那只有对该半成品作同样的处理了,注意,这里面就传入了一个顶级的产成品,最终就可以得到顶级产成品到底级产成品的关系了,最终会获取一个表达式。

将所有的关系存入到数据表中后,需要再进一步处理,就是计算表达式,得到数值为多少。

由于原表设计时没有考虑到主键,因此使用update语句可能会造成计算错误,没有什么好的办法,只有加入一个新的临时表,一行行往里面加入记录。

最后对新表执行一次group by操作,就是想要的结果了。

————————————————————————————-

问题:

该存储过程在vb里面没有办法使用,不知道为什么,也不知道这是不是ado的一个bug,就是在select * from 临时表时,recordset总是返回错误说什么对象关闭时不允许操作。碰到这样的问题也比较烦,因此我最终想出一个办法就是加入一个永久的表,表里面增加一个列为hostid,用hostid来标识操作者的机器,最终返回hostid相关的值。

但在c#里面测试一切正常。

————————————————————————————

在设计过程中碰到的麻烦

1、游标问题:在第一个存储过程中有一个红色的标记local,当时编写时没有加入该标识,总是提示游标已创建。加入后,问题解决。

2、表达式问题:在构建一个表达式后,需要进行计算,在sql server里面似乎没有公式可以计算表达式,然后再返回值的。最终不得不再加入一个游标来进行处理。

3、存储过程中执行存储过程的问题:很是奇怪,为什么不能直接写入存储过程的名称,而必须使用exec?也是郁闷了许久。

————————————————————————————-

相关的csdn中的贴子链接

点击此处

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 一个自认为写得还可以的存储过程,就是没有注释,看起来有点乱。与ERP的BOM相关的-.NET教程,Asp.Net开发
分享到: 更多 (0)