如何写个存储过程?(100分)

  • 主题发起人 主题发起人 chengli
  • 开始时间 开始时间
C

chengli

Unregistered / Unconfirmed
GUEST, unregistred user!
写一个存储过程,每台电话有多条话单,以电话为Group,统计电话及话费,且条件话费不
能少于300,之后又以地区对电话进行统计,如每个区域收入过300地台数。
 
ORACLE8i:

create table 电话费(地区码 number, 电话号码 number, 话费 number)

select 地区码, sum(话费) from
(select 地区码, 电话号码, sum(话费) 话费 from 电话费
group by 地区码, 电话号码 having sum(话费) > 300)
group by 地区码 having sum(话费) > 300
 
>>以电话为Group,统计电话及话费,且条件话费不能少于300
CREATE PROCEDURE MY
RETURNS
(
DQ VARCHAR(20) CHARACTER , //地区
TEL VARCHAR(20) CHARACTER, //电话号码
HF INTEGER //话费
)
AS
BEGIN
for select dq,tel,sum(hf)
from newtable
group by dq,tel
having sum(hf)>300
into :dq:tel,:hf
do
SUSPEND;
END


>>以地区对电话进行统计,如每个区域收入过300地台数
CREATE PROCEDURE MY2
RETURNS
(
DQ VARCHAR(20) CHARACTER , //地区
TS INTEGER //台数
)
AS
BEGIN
for select dq,count(dq)
from my //使用上面的存储过程
group by dq
into :dq,:ts
do
SUSPEND;
END
 
话费300是我们的输入参数,就是不一定为300,该值由我们来定
 
当然是把300当做是参数传入啦!

type TCursor is ref cursor;

create or replace procedure TestProc(p_A1 number, p_A2 number, p_Cursor out TCursor) is
begin
open p_Cursor for
select 地区码, sum(话费) from
(select 地区码, 电话号码, sum(话费) 话费 from 电话费
group by 地区码, 电话号码 having sum(话费) > p_A1)
group by 地区码 having sum(话费) > p_A2;
end;
结果以游标的形式返回, 如果你只有一、两个值的话,也可以不用返回游标:
create or replace procedure TestProc(
p_A1 number,
p_A2 number,
p_S1 out number,
p_S2 out number) is
begin
select 地区码, sum(话费) into p_S1, p_S2 from
(select 地区码, 电话号码, sum(话费) 话费 from 电话费
group by 地区码, 电话号码 having sum(话费) > p_A1)
group by 地区码 having sum(话费) > p_A2;
end;
 
>>以电话为Group,统计电话及话费,且条件话费不能少于输入的参数
CREATE PROCEDURE MY
(
HFZ INTEGER //输入参数
)
RETURNS
(
"DQ" VARCHAR(20) CHARACTER , //地区
TEL VARCHAR(20) CHARACTER, //电话号码
HF INTEGER //话费
)
AS
BEGIN
for select dq,tel,sum(hf)
from newtable
group by dq,tel
having sum(hf)>:hfz
into :dq,:tel,,:hf
do
SUSPEND;
END


>>以地区对电话进行统计,如每个区域收入过输入的参数地台数
CREATE PROCEDURE MY2
(
HFDZ INTEGER //输入参数
)
RETURNS
(
DQ VARCHAR(20) CHARACTER , //地区
TS INTEGER //台数
)
AS
BEGIN
for select dq,count(dq)
from my(:hfdz) //使用上面的存储过程
group by dq
into :dq,:ts
do
SUSPEND;
END
 
homejun:
我用如下存储过程,选择的时候出现了两条相同的记录,从而使第二个存储过程调用的时候
count()的时候,统计数据不对。
CREATE PROCEDURE GET_B (
MINCOST INTEGER
) RETURNS (
AA CHAR(255),
BB CHAR(10),
CC INTEGER
) AS
BEGIN
FOR SELECT distinct zonename,phoneid,count(cost.cost)
FROM cost,zone,phone
WHERE zone.ZONEID=phone.ZONEID
AND phone.PHONEID=cost.PHONEID
group by zonename,phoneid having sum(cost)<:mincost
INTO:AA,:bb,:cc
DO
SUSPEND;
END
 
是最后一项记录每次统计都是多出一项。
 
呵呵,找劳动力啊...哇,别打我的头!
 
为什么在SELECT 后加上distinct,难道不允许每次电话费相同?

当组中有两条记录时当然count(cost.cost)的值为2
 
如果同时要统计大于500,和小于300的台数,且500和300都是可变参数。
 
>>选择的时候出现了两条相同的记录

把WHERE zone.ZONEID=phone.ZONEID
AND phone.PHONEID=cost.PHONEID
改为WHERE phone.ZONEID=zone.ZONEID
AND phone.PHONEID=cost.PHONEID

>>如果同时要统计大于500,和小于300的台数,且500和300都是可变参数。
同志,把上面的存储过程改改就行。看样子你对SQL语言不太懂。可多看SQL语法的书
只靠别人帮忙做软件实在太不现实。cj说的对‘找劳动力啊’,不要事事都让别人做
,不然是学不到真本领的。不要认为给大富翁元又不是人民币就想图省事,自已不动脑
,大富翁也有烦的时候。



 
不好意思,小弟愚钝,没有数据库的基础,加上刚接触InterBase,还得有劳各位仁兄帮忙。仅仅
是毕设项目,时间不多了,还得应付交差,实在没办法。
CREATE PROCEDURE GET_B (
MINCOST INTEGER,
MAXCOST INTEGER
) RETURNS (
AA CHAR(255),
AA1 CHAR(255),
BB CHAR(10),
CC INTEGER,
DD INTEGER
) AS
BEGIN
FOR SELECT zone.zonename,phone.phoneid,SUM(cost.cost)
FROM cost,zone,phone
WHERE zone.ZONEID=phone.ZONEID
AND phone.PHONEID=cost.PHONEID
group by zonename,phoneid having sum(cost)<=:mincost
order by zoneid
INTO:aa,:bb,:cc
DO
FOR SELECT zonename,SUM(cost.cost)
FROM cost,zone,phone
WHERE zone.ZONEID=phone.ZONEID
AND phone.PHONEID=cost.PHONEID
group by zonename,phoneid having sum(cost)>=:maxcost
order by zoneid
INTO:aa1,dd
DO
SUSPEND;
END
如果这样的话,仅仅只能各自统计,没法将之进行联接,有的进行统计,没有的时候记0。
zone >500 <300
a1 0 5
a2 5 0
a3 1 6
还恳请仁兄帮忙指正。
 
最近较忙,现在把代码给你,不过需自己改动,你自已动脑吧!,
有句话叫‘授之以鱼,不如授之以渔’。
select c.dq, s.hf, t.hf from zone c //zone为地区代码表
left join table1 s on c.dq=s.dq // >500的表(当然可以换为存储过程)
left join table2 t on c.dq=t.dq //<300的表
对于空值它不会自动显示为0,你可以通过自行控制显示解决。
 
多人接受答案了。
 
后退
顶部