请教这样一个Stored Procedures该怎么写?(100分)

  • 主题发起人 主题发起人 PLWang
  • 开始时间 开始时间
P

PLWang

Unregistered / Unconfirmed
GUEST, unregistred user!
意思大致是这样 select AVG(所选项目) from tablename where field_1 in TEnum1 //TEnum1是一集合类型
字段field_1为vchar类型 数据取40多个值之一 这40多个值共分5个大类 也就是5个集合了TEnum1-TEnum5 现在要按这个集合
取另一字段的平均值及个数 所选项目是Client端传递上去的参数
以前没写过存贮过程 也不熟悉TSQL里集合如何表示 只好在这里学习了 :)
 
没看懂,举个例子好了。
 
把TEnum1 作为一个字符串 传进去 如 “('条件1','条件2'...,'条件n')”

 
可以利用查询分析器,做下面的工作
--========这个过程是根据不同的人员分类来计算该类人员的固定工资平均数
1、创建过程
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = N'proc_test'
AND type = 'P')
DROP PROCEDURE proc_test
GO
CREATE PROCEDURE proc_test
@PersonTypes varchar(40),
@wFix float output
AS
SELECT @wFix=avg(固定工资) from 工资 where 人员分类 in (@PersonTypes)
2、执行这个过程
Declare @FixWageAvg float
Execute proc_test '在岗,待分,退休,待定',@FixWageAvg output
Select @FixWageAvg

注意:
1、是传出参数一定要用output表示,无论是创建还是调用
2、调用时集中人员类别能是 '在岗,待分,退休,待定'
而不能是 '''在岗'''+','+'''待分'''+','+
'''退休'''+','+'''待定'''




 
应该是我没把问题说清楚 Foonarri的回答我待会再仔细看看 :)
记录共7000多条 field_1一共只有40多个取值可能 比如 教授 副教授 本科 研究生 之类
分成 教师 职工 干部 学生 其他 五类 所选项目是某一个健康指标 因为这40多个以后可能还有变化 所以不能写死在客户端里
select 年龄,AVG(所选项目) as 平均值,count(*) as 个数 from tablename GROUP BY 年龄
所要的SQL大致类似于此 只不过年龄得换成上面说的那五类 但是那五类在表里没有记载
现在想新建一个表a afa存放那40多个值 afb放那五个值 然后就不用存贮过程了 一句select应该就够了
不过我还是写不出来
 
健康指标就假设是“身高”吧
select a.afb,AVG(身高) as 身高平均值,count(*) as 人数
from TAB_EMPLOYEE E
left outer join a
on E.afa=a.afa
group by a.afb

如果所选项目(身高)需由客户端传递
那么,在存储过程中设置一个传入参数@SelectType varchar(10)
然后,将以上sql语句改成
select a.afb,AVG(@SelectType) as 平均值,count(*) as 人数
from TAB_EMPLOYEE E
left outer join a
on E.afa=a.afa
group by a.afb
这样就可以了
 
thank Foonarri 再问一个问题 拿你上文里的E.afa来说 现在存储的数据并不能直接用=来比较 因为存储的格
式是 教授/电子系 这样 所以还得写个函数来取出/前面的字符串
用Delphi来写是:
function search(E.afa : String) : String;
begin
if E.afa<>'' then
if Pos('/',E.afa)=0 then
search:= E.afa
else if Pos('/',E.afa)=1 then
search:= ''
else search:= copy(E.afa,1,Pos('/',E.afa)-1)
else search:= '';
end;
但是在SQL里不知该怎么写 和写在哪?
 
在delphi中的pos函数用charindex(),代替
用法:Charindex('d','wonderful',1) 返回4
| | |
要搜索的 被搜索的 起始位置(可选,默认1)

Declare @s varchar(10)
set @s=left('wonderful',Charindex('d','wonderful',1)-1)
返回'won'
 
create procedure "Get AVG by job"
@Selectedpj varchar(10), @SelectedTable varchar(26) as
select tbclass.class,AVG(@Selectedpj) as 平均值,count(*) as 人数
from @SelectedTable tb1
begin
declare @s varchar(10)
set @s=left(tb1.job,Charindex('/',tb1.job,1)-1)
end
left outer join tbclass
on @s=tbclass.job
GROUP BY tbclass.class
to Foonarri:不知我上面这么写法对不对
你上面所说的@s参数如果要加进去该怎么写 谢谢了 这就散分
 
1、你在帮助中查一下create procedure你就会知道
在Stored Procedure的参数类型中事没有表类型的,你的
select tbclass.class,AVG(@Selectedpj) as 平均值,count(*) as 人数
from @SelectedTable tb1
语句看上去好像是对的,但是,要知道在sql执行时它只会把@SelectedTable解释成
一个字符串而不是一个对象(from字句后面肯定要跟一个对象)
为了实现你的想法,你可以在Delphi中根据变量生成所需要的SQL语句
然后通过Query查询就是了
2、
插入
begin
declare @s varchar(10)
set @s=left(tb1.job,Charindex('/',tb1.job,1)-1)
end
语句实非法的
3、你可以这样:
Delphi代码
...
ADOQuery:TADOQuery;
...
Procedure frmMain.CalcAVG(var sTabName,sType:string);
Begin
if ADOQuery.Active then ADOQuery.Active:=False;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add('select tbclass.class,AVG(' + sType + ') as 平均值,' +
'count(*) as 人数 from ' + sTabName + ' tb1 ' +
'left outer join tbclass ' +
'on left(tb1.job,Charindex(''/'',tb1.job,1)-1)=tbclass.job ' +
'GROUP BY tbclass.class ');
ADOQuery.Active:=True;
End

注意哦,在copy程序时注意我的代码里可以留下的空格哦
要不你要说我写的代码有错了
 
SELECT class.class, AVG(白细胞计数) AS 平均值, COUNT(*) AS 人数
FROM 本院血常规视图 tb1 LEFT OUTER JOIN
class ON LEFT(tb1.职业, CHARINDEX ('/', tb1.职业, 1) - 1) = class.job
GROUP BY class.class
在sqlserver里直接执行时
[microsoft][ODBC SQL Server Driver][SQL Server]Invalid length passed to the substring
function.
tb1.职业有很多是空值 查了一下CHARINDEX 当tb1.职业为NULL时 函数返回NULL 这时CHARINDEX-1就有问题了
这个怎么能避免掉 在GROUP前加了一句where tb1.职业<>'' 问题依旧
 
问题解决了 多谢Foonarri兄 以后有问题再请教
 
多人接受答案了。
 
后退
顶部