求两个个SQL的存储过程(要用到游标)(100分)

  • 主题发起人 主题发起人 xl4772
  • 开始时间 开始时间
X

xl4772

Unregistered / Unconfirmed
GUEST, unregistred user!
在“YFCommon”数据库中,已知:

(1) 表 t_HomeWork5 中存储了订单信息,各字段描述如下:

OrdNo varchar(20) 订单号
COrdNo varchar(50) 客户方的订单号(对客户来说,是他们的采购单号)
PrdtID varchar(20) 产品编码
Name varchar(100) 产品名称
Color varchar(100) 颜色名称
Qty FcFloat 订购数量

要求:(1)写一个存储过程sp_TreeShow,实现对该表的树状层次输出。例如:

OrdNo COrdNo PrdtID Name ColorName Qty
----------- ----------- --------------- --------------- --------------- ------------
050402-004 K2778 PP_212D8R000000 D8开右插 YKK821 456.00000000
050408-028 GS8603 PP_241Y40000000 4#隐勿 YKK580 80.00000000
050418-006 B1 E-06203 PP_212D5L000000 D5开左插 #100 4960.00000000
#149 4360.00000000
#176 3720.00000000
050419-013 C34-403大货 PP_231N7DYD0000 N7勿溶点尾制 红色 9346.00000000
炭灰 5456.00000000
PP_232N7MR00000 N7开金属右插 红色 4673.00000000
炭灰 2728.00000000
050511-005 LY05755 PP_221M3X000000 M3勿线尾制 YKK287 220.00000000
050511-006 LY05754 PP_221M3X000000 M3勿线尾制 YKK306 7356.00000000

即:与上一行相同的内容,则不显示出来。但如果前面列的值已与上一行不同,即使后面某些列的值与上一行相同,都必须显示出来


例如最后一条数据,第一列OrdNo的值已与上一行不同,即使第三列PrdtID的值与上一行相同,但也需要显示出来。


****************************
(2)写一个存储过程sp_TreeSum,按OrdNo,COrdNo,PrdtID,Name统计输出该订单的各产品订购总数PrdtQty(不区分颜色),

并把各颜色分别订购多少用逗号分隔串起来显示ColorQty。无须树状显示。例如:

OrdNo COrdNo PrdtID Name PrdtQty ColorQty
----------- ----------- --------------- --------------- --------------- ------------
050402-004 K2778 PP_212D8R000000 D8开右插 456.00000000 456/YKK821
050408-028 GS8603 PP_241Y40000000 4#隐勿 80.00000000 80/YKK580
050418-006 B1 E-06203 PP_212D5L000000 D5开左插 13040.00000000 4960/#100, 4360/#149, 3720/#176
050419-013 C34-403大货 PP_231N7DYD0000 N7勿溶点尾制 14802.00000000 9346/红色, 5456/炭灰
050419-013 C34-403大货 PP_232N7MR00000 N7开金属右插 7401.00000000 4673/红色, 2728/炭灰
050511-005 LY05755 PP_221M3X000000 M3勿线尾制 220.00000000 220/YKK287
050511-006 LY05754 PP_221M3X000000 M3勿线尾制 7356.00000000 7356/YKK306
 
如果你的数据库内容已经有级次内容的字段,则在程序中用一个递归循环就可以将所有的内容按树形来放置。
如果没有的话,你最好是添加一个字段,将数据库的内容按级别次序用数字或字母来添加新添字段的内容。
 
2、用select sum(Prdtqty) from 表名 group by ordno,cordno,prdtid,name
后头这一问,还没想出来。
 
有没有存储过程实现的阿?
 
这是偶的考试题,表是不能变的
只能用存储过程 用上游标
 
既然能用游标,那就再简单不过了,先用游标遍历整个表,按OrdNo,COrdNo,PrdtID排序遍历,新建一个零时表,最好加一个自增id字段。
一边遍历,一边往零时表插入纪录,判断如果OrdNo值在表中存在,而且PrdtID有不同,那么这笔纪录的OrdNo就插入null。
基本上就是这样了。
 
中午我给你写一个
 
小夏,有没有搞错啊!我布置的作业竟然拿到这里来找答案!
 
被你老师捉到了,哈哈,打pp了
不要说这是我给你写的,就说是自己做的
记住发分
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = N'ShowData'
AND type = 'P')
DROP PROCEDURE ShowData
GO


-- create the store procedure
CREATE PROCEDURE ShowData
AS
create table #tmp(
id int IDENTITY (1, 1) NOT NULL ,
OrdNo varchar(20), --订单号
COrdNo varchar(50), --客户方的订单号(对客户来说,是他们的采购单号)
PrdtID varchar(20), --产品编码
Name varchar(100), --产品名称
Color varchar(100), --颜色名称
Qty decimal(8,2) --订购数量
)
declare @OrdNo varchar(20)
declare @COrdNo varchar(50)
declare @PrdtID varchar(20)
declare @Name varchar(100)
declare @Color varchar(100)
declare @Qty decimal(8,2)

declare @OrdNo2 varchar(20)
declare @COrdNo2 varchar(50)
declare @PrdtID2 varchar(20)
declare @Name2 varchar(100)
declare @Color2 varchar(100)
declare @Qty2 decimal(8,2)

declare @OrdNo3 varchar(20)
declare @COrdNo3 varchar(50)
declare @PrdtID3 varchar(20)
declare @Name3 varchar(100)
declare @Color3 varchar(100)
declare @Qty3 decimal(8,2)

DECLARE dataCR CURSOR For select OrdNo,COrdNo,PrdtID,Name,Color,Qty from t_HomeWork5
order by OrdNo,COrdNo,PrdtID,Name,Color,Qty
open dataCR
FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty --第一行

WHILE (@@FETCH_STATUS = 0)
BEGIN
if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2 and @Name = @Name2 and @Color = @Color2
begin
set @OrdNo3 = ''
set @COrdNo3 = ''
set @PrdtID3 = ''
set @Name3 = ''
set @Color3 = ''
end
else if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2 and @Name = @Name2
begin
set @OrdNo3 = ''
set @COrdNo3 = ''
set @PrdtID3 = ''
set @Name3 = ''
set @Color3 = @Color
end
else if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2
begin
set @OrdNo3 = ''
set @COrdNo3 = ''
set @PrdtID3 = ''
set @Name3 = @Name
set @Color3 = @Color
end
else if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2
begin
set @OrdNo3 = ''
set @COrdNo3 = ''
set @PrdtID3 = @PrdtID
set @Name3 = @Name
set @Color3 = @Color
end
else if @OrdNo=@OrdNo2
begin
set @OrdNo3 = ''
set @COrdNo3 = @COrdNo
set @PrdtID3 = @PrdtID
set @Name3 = @Name
set @Color3 = @Color
end
else
begin
set @OrdNo3 = @OrdNo
set @COrdNo3 = @COrdNo
set @PrdtID3 = @PrdtID
set @Name3 = @Name
set @Color3 = @Color
end

set @OrdNo2 = @OrdNo
set @COrdNo2 = @COrdNo
set @PrdtID2 = @PrdtID
set @Name2 = @Name
set @Color2 = @Color
set @Qty2 = @Qty


insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty) values (@OrdNo3,@COrdNo3,@PrdtID3,@Name3,@Color3,@Qty)

FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty
END

CLOSE dataCR

DEALLOCATE dataCR
select * from #tmp order by id
drop table #tmp
 
to 楼上:
嘿,如果第三行和第一行相同呢?问题虽小,很有意思
 
一个简单的例子,拿去参考
CREATE procedure Derive_ledger
as
declare @BlockId char(2)
declare bId cursor
for select BlockId
from Blocks
for Read Only
open bId
fetch bId into @BlockId
while @@FETCH_STATUS=0
begin
exec Derive_ledger_1 @BlockId
fetch next from bId
into @BlockId
end
close bId

DEALLOCATE bId
 
//这样看着还简单点儿
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = N'ShowData'
AND type = 'P')
DROP PROCEDURE ShowData
GO


-- create the store procedure
CREATE PROCEDURE ShowData
AS
create table #tmp(
id int IDENTITY (1, 1) NOT NULL ,
OrdNo varchar(20), --订单号
COrdNo varchar(50), --客户方的订单号(对客户来说,是他们的采购单号)
PrdtID varchar(20), --产品编码
Name varchar(100), --产品名称
Color varchar(100), --颜色名称
Qty decimal(8,2) --订购数量
)
declare @OrdNo varchar(20)
declare @COrdNo varchar(50)
declare @PrdtID varchar(20)
declare @Name varchar(100)
declare @Color varchar(100)
declare @Qty decimal(8,2)

declare @OrdNo2 varchar(20)
declare @COrdNo2 varchar(50)
declare @PrdtID2 varchar(20)
declare @Name2 varchar(100)
declare @Color2 varchar(100)
declare @Qty2 decimal(8,2)

DECLARE dataCR CURSOR For select OrdNo,COrdNo,PrdtID,Name,Color,Qty from t_HomeWork5
order by OrdNo,COrdNo,PrdtID,Name,Color,Qty
open dataCR
FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty --第一行

WHILE (@@FETCH_STATUS = 0)
BEGIN
if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2 and @Name = @Name2 and @Color = @Color2
begin
insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty)
values ('','','','','',@Qty)
end
else if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2 and @Name = @Name2
begin
insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty)
values ('','','','',@Color,@Qty)
end
else if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2
begin
insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty)
values ('','','',@Name,@Color,@Qty)
end
else if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2
begin
insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty)
values ('','',@PrdtID,@Name,@Color,@Qty)
end
else if @OrdNo=@OrdNo2
begin
insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty)
values ('',@COrdNo,@PrdtID,@Name,@Color,@Qty)
end
else
begin
insert into #tmp(OrdNo,COrdNo,PrdtID,Name,Color,Qty)
values (@OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty)
end

set @OrdNo2 = @OrdNo
set @COrdNo2 = @COrdNo
set @PrdtID2 = @PrdtID
set @Name2 = @Name
set @Color2 = @Color
set @Qty2 = @Qty

FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty
END

CLOSE dataCR

DEALLOCATE dataCR
select * from #tmp order by id
drop table #tmp
 
to uiit 有排序的
注意:最后一列不再处理范围之内
 
to suger:不要唧唧歪歪,谁叫你光练不讲呢,谁叫偶没开数据库的课程呢,谁叫我没用过游标呢。你没看见我没贴出第2个题目吗?--#
 
好啊,大哥能再加点说明吗,我们也可以学学
 
游标在存储过程里面起的是什么作用
 
楼上的,要挨打喽,快去看书啦
 
可以结贴了,可是还是有些不是很明白

to weichao9999:最后几行里面的
set @OrdNo2 = @OrdNo
set @COrdNo2 = @COrdNo
set @PrdtID2 = @PrdtID
set @Name2 = @Name
set @Color2 = @Color
set @Qty2 = @Qty

FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty

是什么意思?有没有必要放在这里,能不能删掉?!
我的理解是:拿第一行和第二行比较,比较的结果写到第三行,然后第二行作为第一行和下面一行比较。。。
理解错误请指正:)
那么这里的FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty
又能不能删掉呢?

请知道的朋友指点一下。。。
 
weichao9999老师

WHILE (@@FETCH_STATUS = 0)
BEGIN
if @OrdNo=@OrdNo2 and @COrdNo = @COrdNo2 and @PrdtID = @PrdtID2 and @Name = @Name2 and @Color = @Color2

这里=@OrdNo2 ,@COrdNo2,@PrdtID2 。。这些都没有赋值怎么就开始用于判断了
 
既然wei老师写了那么多行,我就说说了
to weichao9999:
我说的意思:你只是逐行比较而已,第一行和第二行,然后第二行和第三行,依次...
如果第一行和第二行不同,而第三行又和第一行前几个字段相同时,你就不会正确结果了了。当然除非你的表排序过(楼主好像没有这么说),而像qcchan写个递归通用性就更强一些。
to 楼主:
你还没有正确理解游标的用法
-- 带2的变量相当于中间变量,用来与游标所在行作比较,然后相同的写空,不同的写
-- 入里临时表
-- 下面的意思是,把当前游标所在行的字段值赋给中间变量,然后指向游标下一行
-- 说白了wei老师程序每次的比较就是逐行比较(除了第一行外)2与1,3与2,4与3...
set @OrdNo2 = @OrdNo
set @COrdNo2 = @COrdNo
set @PrdtID2 = @PrdtID
set @Name2 = @Name
set @Color2 = @Color
set @Qty2 = @Qty
{-- 第一次指向第一条纪录
FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty --第一行
-- while循环,直到最后一条
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- 指向下一条
FETCH NEXT FROM dataCR into @OrdNo,@COrdNo,@PrdtID,@Name,@Color,@Qty}
END
-- 上面是保证游标移动的,当然不能删,删了你的游标怎么指向下一条纪录?
-- 再看看游标(西西)
游标的意思,其实就是只想你所取得表中一行一行记录,通过以上循环,来实现你的
一条一条纪录的访问。
 
后退
顶部