一个简明的ERP存储过程实例
2005-04-14 09:21
483 查看
一个自认为写得还可以的存储过程,就是没有注释,看起来有点乱。与ERP的BOM相关的图示如下:
所使用数据库 : SQL Server 2000,数据表名:Te(乱七八糟命名的)表结构:
最终需要输出结果
即一单位产成品需要底级半成品的数量以及半成品的名称。比如说半成品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?也是郁闷了许久。
-------------------------------------------------------------------------------------
所使用数据库 : SQL Server 2000,数据表名:Te(乱七八糟命名的)表结构:
varchar(20) | varchar(20) | decimal(20,4) |
Assbom | point | sl |
产成品 | 半成品1 | 2 |
产成品 | 半成品2 | 3 |
产成品 | 半成品3 | 2 |
半成品1 | 半成品4 | 2 |
半成品1 | 半成品5 | 2 |
半成品3 | 半成品5 | 3 |
Assbom | point | sl |
产成品 | 半成品2 | 3 |
产成品 | 半成品4 | 4 |
产成品 | 半成品5 | 13 |
存储过程如下:(呵呵,命名就别讲究了,我没有太过于留意)
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?也是郁闷了许久。
-------------------------------------------------------------------------------------
相关文章推荐
- 一个存储过程实例
- mysql存储过程的一个完整实例
- 一个自认为写得还可以的存储过程,就是没有注释,看起来有点乱。与ERP的BOM相关的
- MSSQL数据库:存储过程实例学习(1)从两个表中取出头两行,然后合并到一个表中
- 一个使用游标的存储过程的实例
- SQL SERVER 2000 连接ORCLE数据库 (加了一个存储过程的实例)
- 关于一个简单的mysql存储过程实例
- SQL Server一个实例中调用另外一个实例中的存储过程
- 写一个简单的存储过程实例的笔记
- 简单的存储过程实例2--对比三个表中的数据,将三个表中金额挑选一个最优值
- MYSQL存储过程的一个完整实例
- SQL Server一个实例中调用另外一个实例中的存储过程
- sql的存储过程实例--动态根据表数据复制一个表的数据到另一个表
- 存储过程的一个简单实例
- sql plus创建一个简单的存储过程实例
- Oracle存储过程基本语法与基础教程(简明清楚且附实例)
- .若A,B两个实体是一对多的包含关系。利用存储过程,实现数据访问层层的一个实例。
- 保存一个package的存储过程的实例
- MySQL存储过程使用实例详解
- MySql 存储过程实例(附完整注释)