一百分求变态SQL代码,在线等。答对全得。

破碎的脸 2006-10-29 02:14:55
这是一个网吧管理系统。
首先在SQL里用getdate()得到当前登陆时间,然后以预存金额与所定义的时段收费(时段收费是在另一张表中,有二十四个字段,从零到二十三,里面记录了每个小时的收费标准)进行减运算,逐一相减,比如20块,现在时间为晚上八点,那么就是20-八点收费标准-九点收费标准以此类推,直到小于或等于1,然后用余数与下一个时段收费标准进行相除,得出所能上网的时长,精确到分,然后与当前登陆时间进行相加,然后得出预计下机时间。
第一个做出来的送分一百,只能在SQL里完成,不能使用其它代码,当然如果有JAVA代码或者C#代码作参考,会补送一些补偿分。请高手帮忙!
...全文
1090 41 打赏 收藏 举报
写回复
41 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
破碎的脸 2006-10-31
  • 打赏
  • 举报
回复
kardkard() 下次我发贴的时候请跟贴,一并送分。。。谢谢你的帮助。。。
analysefirst 2006-10-30
  • 打赏
  • 举报
回复
倒,这种SQL语句也叫变态?!
philoo 2006-10-30
  • 打赏
  • 举报
回复
发现[用户上网信息]和[历史记录管理]几乎是相同的字段,不知干吗做成2个表
philoo 2006-10-30
  • 打赏
  • 举报
回复
多在设计数据库结构上下点功夫,尽量设计合理有效的数据库表结构,哎
philoo 2006-10-30
  • 打赏
  • 举报
回复
set @h_fee=convert(float,(select @f_name from 各时段收费标准))
就是这句,其中的(select @f_name from 各时段收费标准)查询结果是什么?
是@f_name的值,也就是当@f_name为'零'的时候,(select @f_name from 各时段收费标准)的查询结果是:'零',你要把'零'转换为float,当然给你如下提示:

服务器: 消息 8114,级别 16,状态 5,行 3
将数据类型 varchar 转换为 float 时出错。


Ivony 2006-10-30
  • 打赏
  • 举报
回复
首先在SQL里用getdate()得到当前登陆时间,然后以预存金额与所定义的时段收费(时段收费是在另一张表中,有二十四个字段,从零到二十三,里面记录了每个小时的收费标准)进行减运算,逐一相减,比如20块,现在时间为晚上八点,那么就是20-八点收费标准-九点收费标准以此类推,直到小于或等于1,然后用余数与下一个时段收费标准进行相除,得出所能上网的时长,精确到分,然后与当前登陆时间进行相加,然后得出预计下机时间。
每分钟进行一次检查,查看现在时间是否>=下机时间-5分钟,如果达到这一标准则弹出提示,要求用户续费,如果现在时间>=下机时间,自动发送换机命令,对客户机屏幕进行锁定,并将这条记录删除,同时起动触发器,把所需要的值写进收入统计。
检查同时,对用户进行时间验证,如果满足扣费标准(用户自定义时间,比如30分钟扣一次,或者15分钟扣一次,首次扣费以初始时间为准,比如开卡后5分钟开始扣费,或者10分钟,同样是用户自定义的),进行扣费,直到余额为零。如果用户中途结账,计算出剩余金额。并将所有收入放到收入统计表里。


汗……
你在后面新建一个字段,每个小时把用户的费用计算一次存进去(只需要加上本小时的就行了),并检查是不是已经透支,这样不就简单多了……

昏迷中……
fishmans 2006-10-30
  • 打赏
  • 举报
回复
这个收费表干嘛要用24个字段??用一个字段,很容易算出收费情况啊
aixiangtouzhu 2006-10-30
  • 打赏
  • 举报
回复
我晕,高手
就是有些不清晰了
储存过程!
喝醉的咖啡 2006-10-30
  • 打赏
  • 举报
回复
再说,你的计费方式也是线性计费,还不算很复杂,楼上的方法稍微有点儿笨拙,不妨考虑参考计算 个人收入所得税 的方式(借助数组可以把代码更加优化,容易理解和维护)。
喝醉的咖啡 2006-10-30
  • 打赏
  • 举报
回复
小菜一碟啦,我设计的系统用来在虚拟社区中动态配置和计算不同操作的计分情况等等,例如登录一次加 xx 值 n 点,同时加 xxx 值 m 点,减体力值 x 点等等


主要用到一个存储过程来进行判断操作
另外用一个 job 来每分钟调用该存储过程

事实上,以前开发门户网站的时候为了解决跨服务器之间的 Session 连贯,没有采用 IIS 的Session,借助数据库实现了一个 Session 机制,原理、目的与你的都很接近。

无非在定时执行的存储过程中进行一些 "switch" 罢了


另外,还利用了存储过程的一个优势:可以在线更改
——也就是说,当管理员更改了计费判断规则,可以用程序更新该存储过程,以便达到0维护的目的。

具体代码没工夫写下去了,那么多热心兼优时间的朋友给你写了
破碎的脸 2006-10-30
  • 打赏
  • 举报
回复
create proc compute_getoff_time @card_num varchar(7),@ret datetime output as --建立存储过程
begin
declare @count_hour float --变量float类型,小时
set @count_hour=0 --设置其值为0
declare @tem_card varchar(50) --变量卡号
set @tem_card=@card_num --设置卡号=卡号
declare @geton_time datetime,@yajin float --变量datetime类型和float类型
select @geton_time=上机时间,@yajin=预存金额 from 用户上网信息 where 卡号 =@tem_card --查询并代值
declare @h float,@f_name varchar(50) --变量h float类型,变量名字
set @f_name='' --设置名字为空
set @h=DATEPART(Hour, @geton_time)--读得小时值的系统函数,我找不到
declare @h_fee float --时段变量压金

--这里是变量表,ount_hour小时总数,tem_card卡号,getton_time上机时间,yajin预存金额
while @yajin>0 --只要压金还没减完,就循环
begin
set @f_name=
case @h
when 0 then '零'
when 1 then '一'
when 2 then '二'
when 3 then '三'
when 4 then '四'
when 5 then '五'
when 6 then '六'
when 7 then '七'
when 8 then '八'
when 9 then '九'
when 10 then '十'
when 11 then '十一'
when 12 then '十二'
when 13 then '十三'
when 14 then '十四'
when 15 then '十五'
when 16 then '十六'
when 17 then '十七'
when 18 then '十八'
when 19 then '十九'
when 20 then '二十'
when 21 then '二十一'
when 22 then '二十二'
when 23 then '二十三'
end
set @h_fee=convert(float,(select @f_name from 各时段收费标准) --查询出当前小时收费标准h_fee
if(@yajin>@h_fee) --如果压金大于这个收费标准
begin
set @yajin=@yajin-@h_fee --则相减
set @count_hour=@count_hour+1 --小时数加一
end
else
begin --如果不大于的时候,小时数增加压金除以当前收费标准
set @count_hour=@count_hour+round(@yajin/@h_fee,3)--押金能上几个小时,对小时保留3位小数
set @yajin=@yajin-@h_fee --压金减当前收费标准
end
set @h=@h+1
end
set @ret=dateadd(hour,@count_hour,@geton_time)
end

服务器: 消息 8114,级别 16,状态 5,过程 compute_getoff_time,行 45
将数据类型 varchar 转换为 float 时出错。

查询结果是2.0而h_fee是float类型,为什么会报错???
set @h_fee=convert(float,(select @f_name from 各时段收费标准)
就是这句
kardkard 2006-10-30
  • 打赏
  • 举报
回复
哦,呵呵!
kardkard 2006-10-30
  • 打赏
  • 举报
回复
哦,有点小问题!再改一下!
declare @收费表 table(
f0 decimal(18,2),
f1 decimal(18,2),
f2 decimal(18,2),
f3 decimal(18,2),
f4 decimal(18,2),
f5 decimal(18,2),
f6 decimal(18,2),
f7 decimal(18,2),
f8 decimal(18,2),
f9 decimal(18,2),
f10 decimal(18,2),
f11 decimal(18,2),
f12 decimal(18,2),
f13 decimal(18,2),
f14 decimal(18,2),
f15 decimal(18,2),
f16 decimal(18,2),
f17 decimal(18,2),
f18 decimal(18,2),
f19 decimal(18,2),
f20 decimal(18,2),
f21 decimal(18,2),
f22 decimal(18,2),
f23 decimal(18,2)
)
insert into @收费表 values(1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.0,1.1,1.2,1.3)

--select * from @收费表

declare @now datetime--时间
declare @sum decimal(18,2)--金额
declare @end datetime--下一个收费点
declare @mi int
set @now=getdate()
set @sum=10
set @mi=0



set @end=@now
while @sum>0
begin
while datediff(HH,dateadd(mi,@mi,@end),@end)=0
begin
set @mi=@mi+1
end

select @sum=@sum-(case datepart(HH,@end)
when 0 then f0
when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
when 9 then f9
when 10 then f10
when 11 then f11
when 12 then f12
when 13 then f13
when 14 then f14
when 15 then f15
when 16 then f16
when 17 then f17
when 18 then f18
when 19 then f19
when 20 then f20
when 21 then f21
when 22 then f22
else f23
end )*@mi/60
from @收费表
set @end=dateadd(mi,@mi,@end)
print @end
print @sum

end

if @sum<0
begin
select @end=dateadd(mi,@sum*60/(case datepart(HH,dateadd(mm,-@mi,@end))
when 0 then f0
when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
when 9 then f9
when 10 then f10
when 11 then f11
when 12 then f12
when 13 then f13
when 14 then f14
when 15 then f15
when 16 then f16
when 17 then f17
when 18 then f18
when 19 then f19
when 20 then f20
when 21 then f21
when 22 then f22
else f23
end )+60,dateadd(mm,-@mi,@end))
from @收费表
end


print @end
破碎的脸 2006-10-30
  • 打赏
  • 举报
回复
baby97,很抱歉,可能是我的技术不到位,不能理解阁下的精妙代码,不过还是非常感谢你和大家的帮助,承诺baby97 30分,本想一并给了的,不过不知道为什么不能追加分上去了。。。。如果你以后看到我的贴子欢迎跟上一贴,一并补上,乔峰兄的代码有个小小的逻辑错误,我已经改过了,可以用,很感谢。。。花了两个小时,原来还不到各位高手所学的一点皮毛。。。。
谢谢大家!请以后多指教。
QQ群:22629823
kardkard 2006-10-30
  • 打赏
  • 举报
回复
代码一大片,把我都搞糊涂了,看了一下 blackant2(乔峰) 的代码,虽然数据库表设计得不太理想,但也能够用,所以我在他的基础上改了一下,楼主看一下成不成!

declare @收费表 table(
f0 decimal(18,2),
f1 decimal(18,2),
f2 decimal(18,2),
f3 decimal(18,2),
f4 decimal(18,2),
f5 decimal(18,2),
f6 decimal(18,2),
f7 decimal(18,2),
f8 decimal(18,2),
f9 decimal(18,2),
f10 decimal(18,2),
f11 decimal(18,2),
f12 decimal(18,2),
f13 decimal(18,2),
f14 decimal(18,2),
f15 decimal(18,2),
f16 decimal(18,2),
f17 decimal(18,2),
f18 decimal(18,2),
f19 decimal(18,2),
f20 decimal(18,2),
f21 decimal(18,2),
f22 decimal(18,2),
f23 decimal(18,2)
)
insert into @收费表 values(1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.0,1.1,1.2,1.3)

--select * from @收费表

declare @now datetime--时间
declare @sum decimal(18,2)--金额
declare @end datetime--下一个收费点
declare @mi int
set @now=getdate()
set @sum=10
set @mi=0



set @end=@now
while @sum>0
begin
while datediff(HH,dateadd(mi,@mi,@end),@end)=0
begin
set @mi=@mi+1
end

select @sum=@sum-(case datepart(HH,@end)
when 0 then f0
when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
when 9 then f9
when 10 then f10
when 11 then f11
when 12 then f12
when 13 then f13
when 14 then f14
when 15 then f15
when 16 then f16
when 17 then f17
when 18 then f18
when 19 then f19
when 20 then f20
when 21 then f21
when 22 then f22
else f23
end )*@mi/60
from @收费表
set @end=dateadd(mi,@mi,@end)
print @end
print @sum

end

if @sum<0
begin
select @end=dateadd(mi,@sum*60/(case datepart(HH,dateadd(hh,-1,@end))
when 0 then f0
when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
when 9 then f9
when 10 then f10
when 11 then f11
when 12 then f12
when 13 then f13
when 14 then f14
when 15 then f15
when 16 then f16
when 17 then f17
when 18 then f18
when 19 then f19
when 20 then f20
when 21 then f21
when 22 then f22
else f23
end )+60,dateadd(hh,-1,@end))
from @收费表
end


print @end
lovvver 2006-10-30
  • 打赏
  • 举报
回复
楼主怎么不把这些问题拿到Sql server版去问呢?
破碎的脸 2006-10-30
  • 打赏
  • 举报
回复
CREATE TRIGGER [TRIGGER NAME] ON [dbo].[附加商品管理]
FOR UPDATE
AS
declare @sum int,@sell float,@buy float,@name varchar(50)--之前的商品数量,卖价,进价
declare @asum int --之后的数量
if update([商品数量])
begin
select @sum=[商品数量],@sell=[商品卖价],@buy=[商品进价],@name=[商品名称] from deleted --得到交易前的值以及名称
set @asum=(select [商品数量] from inserted) --得到交易后的数量
if @asum<0
begin
rollback --撤销交易
end
else
begin
insert 附加商品经营情况([商品名称],[卖出数量],[销售时间],[单次交易总价],[单次交易利润]) values(@name,@sum-@asum,getdate(),(@sum-@asum)*@sell,(@sum-@asum)*(@sell-@buy))
end
end

花了两个小时,学会了一些简单的SQL,恭喜自己,请高手们继续指导我,一起完成这道BT至极的SQL题。。。
破碎的脸 2006-10-30
  • 打赏
  • 举报
回复
jcyluck()
when 0 then 1.0000
when 1 then 1.0000
when 2 then 1.0000
when 3 then 1.0000
when 4 then 1.0000
when 5 then 1.0000
when 6 then 1.0000
when 7 then 1.0000
when 8 then 1.0000
when 9 then 1.0000
when 10 then 1.0000
when 11 then 1.0000
when 12 then 2.0000
when 13 then 2.0000
when 14 then 2.0000
when 15 then 2.0000
when 16 then 2.0000
when 17 then 2.0000
when 18 then 2.0000
when 19 then 2.0000
when 20 then 2.0000
when 21 then 2.0000
when 22 then 2.0000
when 23 then 2.0000

可能是我理解上有点问题,因为字段名不是2.0000也不是1.0000而是中文的。感谢帮助,贴时送上20分
破碎的脸 2006-10-30
  • 打赏
  • 举报
回复
哎。。。。。。我是才殊学浅。。。。。所以先谢谢大家了。。。。对了wumylove1234(毁于随) 的那句。。。。我要证明一点就是。。。。我是以分来吸引大家,以情来打动大家,以礼来答谢大家。。。。。还有,我做这个不是用的.net当然也不会用到IIS,数据库是用的SQL Server,而代码是Java SE。。。。
ycqing 2006-10-30
  • 打赏
  • 举报
回复
ding
加载更多回复(21)
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2006-10-29 02:14
社区公告

让您成为最强悍的C#开发者