急救,在线等

beckhim 2004-10-02 08:40:58
数据库中有两个表,一个为T_Cards,保存游戏卡信息,其中游戏卡可以分为很多种类如:A,B,C;另一个表为T_Record,保存游戏卡的出入库记录,比如说现在将10张A类卡入库,则在T_Record中增加一条记录:A类卡入库前的数量,入库的数量,入库后的数量;出库也一样的增加一条记录.
应该怎么做?请大虾们指点,谢谢
...全文
190 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
General521 2004-10-03
  • 打赏
  • 举报
回复
beckhim() 我看你现在是越说越糊涂了.现在唯一的最好的办法就是将你的过程设计全部抛弃,因为你的设计很不和理.
现在最好重新设计一个合理的计划,这样对编程和以后的维护都会有不可估量的好处;如果你的数据库设计的不和理,那么以后就会给你带来很多麻烦,甚至是完全失败.
yjdn 2004-10-03
  • 打赏
  • 举报
回复
游戏卡名称 出/入库前数量 出/入库数量 出/入库后数量
A 0 4 4
A 4 -2 2
------------------------
你是说,出库两张卡,也只记录在一个记录上?

是不是这样:
不管出库入库,只要T_Record中的最后一个记录的用户和T_cards插入记录的用户相同,那就只在一个记录上记录?
beckhim 2004-10-03
  • 打赏
  • 举报
回复
只要拥有者不是system,就表示这张卡就已经从系统库存中出库了,出库的实际意义并不是说从数据库中出来,这里的库表示游戏卡的库存,不管是系统或是经销商,他们的库存都是在T_Cards中反应出来的,但具体一张卡是谁的库存是由Owner字段反应出来的,比如说现在系统有A卡的四个库存,那四张卡的Owner都是system,这时经销商P1向系统购2张A卡(具体是哪一个卡号这是由系统自动分配的),那原先那四张A卡就有两张的Owner改为P1,这时就表示系统已经出库了两张A卡。
yjdn 2004-10-03
  • 打赏
  • 举报
回复
没错,拥有者可能随时改变,因为卡是卖来卖去的,一会可以是经销商,一会可能是直销商,但是我只要统计来源为system拥有者也是system的卡A的数量。
--------------------------------------
你统计system是入库,那出库呢?哪一个拥有者才算是出库?(因为出库和入库在一个触发器中解决)
beckhim 2004-10-03
  • 打赏
  • 举报
回复
**卡来源不同,是不是拥有者也不同?
**那这样的话,拥有者一多以后,你怎么判断是存还是出?

没错,拥有者可能随时改变,因为卡是卖来卖去的,一会可以是经销商,一会可能是直销商,但是我只要统计来源为system拥有者也是system的卡A的数量。

入库会有insert into操作,出库会有update操作,就是将拥有者从system修改为某经销商或直销商。
beckhim 2004-10-03
  • 打赏
  • 举报
回复
yjdn(无尽天空)你好,可能我表达的不够清楚,你可不可以按照你的思路将我的操作过程修改一下按然后出你实现的触发器,我不想加一张卡就在T_Record加入一条记录,比如我一次增加了四张A类卡,虽然有四次插入操作,但我希望在T_Record中只有一条记录。谢谢
beckhim 2004-10-03
  • 打赏
  • 举报
回复
yjdn(无尽天空),看你的测试结果是没有问题,就是要这样的效果,我再在我的实际应用中试一下,先谢
yjdn 2004-10-03
  • 打赏
  • 举报
回复
真麻烦啊,
如果这样还不能满足楼主的要求,那就先请楼主把这帖结了,
再另开一个帖,把详细的操作过程和表列出来了。
yjdn 2004-10-03
  • 打赏
  • 举报
回复
--增加一个标识列
alter table T_Record add ID int identity(1,1)

--创建触发器
create trigger tri_cards
on dbo.T_cards
for insert ,update
as
declare
@Cardname varchar(10),
@lastCardname varchar(10),
@beforeChange int,
@AfterChange int,
@user varchar(10),
@lastuser varchar(10),
@ID int,
@num int,
@lastnum int
begin
----------------------------------取得插入的卡号,拥有人
select @Cardname=游戏卡名称,@user=拥有人 from inserted
---------------------------------取得对应卡名的最后一次更新的后数量,
select @beforechange=[出/入库后数量],@id=ID ,@lastnum=[出/入库数量] from T_Record
where ID in
(select Max(ID) from T_Record where 游戏卡名称=@cardname)

--------------------------------判断是存入还是取出
if left(cast(@lastnum as char(10)),1)<>'-'
begin
set @lastuser='system'
end
else
begin
set @lastuser='出库'
end
-----------------------判断出入库表中最后一条记录的游戏卡名称是否是刚插入的游戏卡名称
if exists(select 游戏卡名称 from T_Record where 游戏卡名称=@Cardname and id
in (select max(id) from T_Record))
begin
----------------------------入库,且最后一个记录是入库时,更新
if @user='system' and @lastuser='system'
begin
update T_Record set [出/入库数量]=[出/入库数量]+1,
[出/入库后数量]=[出/入库后数量]+1 where id=@id

end
----------------------------入库,最后一个记录不是入库时,插入记录
else if @user='system' and @lastuser<>'system'
begin
insert into T_Record(游戏卡名称,[出/入库前数量],[出/入库数量],
[出/入库后数量]) values(@cardname,@BeforeChange,1,@BeforeChange+1)
end
-----------------------------出库,最后一个记录是入库时,插入
else if @user<>'system' and @lastuser='system'
begin
---------------------------------出库前数量不够,出错
if @BeforeChange=0
begin
print '没有出/入库预期的数量'
end
else
begin
insert into T_Record(游戏卡名称,[出/入库前数量],[出/入库数量],
[出/入库后数量]) values(@cardname,@BeforeChange,-1,@BeforeChange-1)
end
end

------------------------------出库,最后一个记录不是入库时,更新
else if @user<>'system' and @lastuser<>'system'
begin

if @BeforeChange=0
begin
print '没有出/入库预期的数量'
end
else
begin
update T_Record set [出/入库数量]=[出/入库数量]-1,
[出/入库后数量]=[出/入库后数量]-1 where id=@id
end
end
end
-----------------------------不存在相应的记录时
else
begin
----------------------------入库时
if @user='system'
begin
insert into T_Record(游戏卡名称,[出/入库前数量],[出/入库数量],
[出/入库后数量]) values(@cardname,0,1,01)
end
else
----------------------------出库时,出错
begin
print '没有出/入库预期的数量'
end

end

end



--测试1
insert into T_Cards select 'A','c0001','c0001','system','system'
insert into T_Cards select 'A','c0002','c0002','system','system'
insert into T_Cards select 'A','c0003','c0003','system','system'
insert into T_Cards select 'A','c0004','c0004','system','system'
--你也可以一条条插入测试
--结果:
ID 游戏卡名称 出/入库前数量 出入库数量 出/入库数量
1 A 0 4 4

--测试2
update T_Cards set 拥有人='p1' where 卡号='c0001'
update T_Cards set 拥有人='p1' where 卡号='c0003'
--结果:如果ID是添加上去的,ID显示在最后

ID 游戏卡名称 出/入库前数量 出入库数量 出/入库数量
1 A 0 4 4
2 A 4 -2 2




--测试3
insert into T_Cards select 'B','B0001','B0001','system','system'
insert into T_Cards select 'B','B0002','B0002','system','system'
insert into T_Cards select 'B','B0003','B0003','system','system'
insert into T_Cards select 'B','B0004','B0004','system','system'


update T_Cards set 拥有人='p2' where 卡号='B0001'
update T_Cards set 拥有人='p2' where 卡号='B0003'
--结果
ID 游戏卡名称 出/入库前数量 出入库数量 出/入库数量
1 A 0 4 4
2 A 4 -2 2
3 B 0 4 4
4 B 4 -2 2

yjdn 2004-10-03
  • 打赏
  • 举报
回复
如果你增加一个标识字段ID,可以做到,但你要判断的东西太多了,
麻烦,正在解决中....
General521 2004-10-02
  • 打赏
  • 举报
回复
create trigger clk
on T_Cards
for update
as
declare @a varchar(8000)
declare @b int
declare @c int
declare @d int
if update(某类卡数量字段)
begin
select @a=类型 from inserted
select @b=游戏卡数量 from deleted --A类卡入库前的数量
select @c=游戏卡数量 from inserted --入库后的数量
select @d=@c-@b --入库的数量
insert into T_Record
values(@a,@b,@d,@c)
if @@error<>0 ----为了提高系统的完整性与一致性,最好加上这个错误判断语句.
begin
rollback transaction
return
end
end
go
**************************************************************************************
在上面的语句中
select @a=类型 from inserted --将你要增加数量的游戏卡类型赋到@a变量中.
select @b=游戏卡数量 from deleted --将A类卡入库前的数量赋到@b变量中.
select @c=游戏卡数量 from inserted --将A类卡入库后的数量赋到@c变量中
select @d=@c-@b --将A类卡入库的数量赋到@d变量中
针对你的问题:
"对了,我补充一下,游戏卡出库并不需要在T_Cards表中将游戏卡记录删除,而是将其中一个字段(Owner)的值改变一下就可以了。出库和入库都使用同一个触发器吗?谢谢"
说明:这个触发器并没有在T_Cards表中将游戏卡记录人为的显示的删除,上面出现的deleted和inserted只是支持触发器工作的临时表(是在系统内部生成的).
我可以这样跟你解释:
对数据的更新,在DBMS中实际上对数据进行的是两步操做:
1:先删除你要更新的旧记录
2:然后再将你更新后的新记录插入到数据表中
而触发器恰恰显示的证明了这一点.

'出库和入库都使用同一个触发器吗?谢谢'
答;当然可以.
zjcxc 2004-10-02
  • 打赏
  • 举报
回复

T_Record
字段名:CardName BeforeChange Amount AfterChange
说明: 游戏卡名称 出/入库前数量 出/入库数量 出/入库后数量




数量从那里来?? 根据什么判断出库/入库?
beckhim 2004-10-02
  • 打赏
  • 举报
回复
我详细说一下表的结构
T_Cards:
字段名:CardName CardNumber PassWord Owner ComeFrom
说明: 游戏卡名称 卡号 密码 拥有人 卡的来源

T_Record
字段名:CardName BeforeChange Amount AfterChange
说明: 游戏卡名称 出/入库前数量 出/入库数量 出/入库后数量

其中ComeFrom表示是谁入库的卡,如果是系统,ComeFrom为"system",如果是经销商则为经销商的账号,现在我只需记录系统的出入库记录(也就是说ComeFrom字段的值一但写入就不会更改),比如说系统入库一张新卡,则在T_Cards中增加一条记录(这时Owner为"system",ComeFrom为"system"),而这时有经销商p1从系统买了一张卡,那这时T_Cards表中所以应的刚刚买的这张卡的Owner字段值就会改为"p1",而ComeFrom的值不会变。
beckhim 2004-10-02
  • 打赏
  • 举报
回复
你好 General521(dhy) 我以前没做过触发器,所以有些看不懂,你能不能稍为我解释一下如下语句?万分感谢

select @a=类型 from inserted
select @b=游戏卡数量 from deleted --A类卡入库前的数量
select @c=游戏卡数量 from inserted --入库后的数量

对了,我补充一下,游戏卡出库并不需要在T_Cards表中将游戏卡记录删除,而是将其中一个字段(Owner)的值改变一下就可以了。出库和入库都使用同一个触发器吗?谢谢
General521 2004-10-02
  • 打赏
  • 举报
回复
如果你的表设计合理的话:先做一个简单的假设:
你的T_Cards的表的结构为:
(类型 varchar(8000) primary key,游戏卡数量 int )
你的T_Record表的结构为:
(类型 varchar(8000),A类卡入库前的数量 int,入库的数量 int,入库后的数量 int)
针对这种情况:
在你的T_Cards表上创建触发器:
create trigger clk
on T_Cards
for update
as
declare @a varchar(8000)
declare @b int
declare @c int
declare @d int
if update(某类卡数量字段)
begin
select @a=类型 from inserted
select @b=游戏卡数量 from deleted --@b为A类卡入库前的数量
select @c=游戏卡数量 from inserted --@c为A类卡入库后的数量
select @d=@c-@b --@d为A类卡入库的数量
insert into T_Record
values(@a,@b,@d,@c)
if @@error<>0 ----为了提高系统的完整性与一致性,最好加上这个错误判断语句.
begin
rollback transaction
return
end
end
go
这种思路(方法)完全可以解决你的问题,不过具体的表设计还要楼主根据具体情况来设计.

General521 2004-10-02
  • 打赏
  • 举报
回复
你要先解决表设计问题。我们才可以帮你解决实现问题。
yjdn 2004-10-02
  • 打赏
  • 举报
回复
卡来源不同,是不是拥有者也不同?
那这样的话,拥有者一多以后,你怎么判断是存还是出?
yjdn 2004-10-02
  • 打赏
  • 举报
回复
你要想达到上面的效果,我觉得你得在T_Record表加一个标识列,要不然就得用到临时表来解决,
而且数据大的时候,用临时表效率不行。
--如果是加标识的话,用我上面那个触发器改一下就可以了,@option 用于判断拥有者是谁。
时间字段相当于标识字段.


--如果你想每加入一张卡就在T_Record加入一记录,那又另当别论
beckhim 2004-10-02
  • 打赏
  • 举报
回复
卡的来源不一定只一个system,也可能有经销商,来源不同时操作也没什么不同,购卡时会判断向谁购卡,不管来源是谁,只要owner是你,别人就可以购你的这张卡,现在可以假设来源全部都是system.
yjdn 2004-10-02
  • 打赏
  • 举报
回复
卡的来源就只有一个system?如果不是,来源不同的时候,操作有什么不同
加载更多回复(10)

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧