注册 登录
编程论坛 SQL Server论坛

关于触发器的问题

上帝之允 发布于 2010-10-11 21:58, 1465 次点击
我刚自学了触发器,想做一个药的数据库
目的是向入库清单中插入数据的时候,希望药库也相应改变
可是只能改变第一次插入入库清单时的药品,不知道为什么,请指教
if object_id('Trigger1','TR')is not null
drop Trigger Trigger1;
go
create trigger Trigger1 on 入库清单
after insert
as
declare @number int,@name varchar(15);
select @number=medician_number,@name=medician_name from inserted
if(@name not in(select medician_name from 药库))
begin
insert into 药库(medician_name,medician_store,修改日期)
select @name,@number,date
from inserted
end
else
begin
insert into 药库
select @name,@number+medician_store,date
from inserted,药库
where @name=药库.medician_name and 修改日期=(select top 1
修改日期 from 药库 order by 修改日期 desc)
end
go
23 回复
#2
gameohyes2010-10-11 23:00
按照你讲的作用做了个类似的.(看看是否符合)
程序代码:
use master
drop table temp
create table temp(
    id int not null primary key identity(1,1),
    sj int not null
)
drop table temp1
create table temp1(
    id int not null primary key identity(1,1),
    sj int not null,
)
drop trigger tri_temp
create trigger tri_temp
on temp
for insert
as
if((select sj from inserted) not in(select sj from temp1))
begin
    insert into temp1 select sj from inserted
end
else
begin
    update temp1 set sj=sj+(select sj from inserted)
where id=(select id from temp1 where sj in(select sj from inserted))
end
insert into temp values(132)
select * from temp
select * from temp1
#3
上帝之允2010-10-11 23:17
好像还是不行,我不明白为什么每次药库里改变的都是第一次输入入库清单里的药品
我的药库,没有主键,是记录每次药品的增长之后的库存的。
#4
gameohyes2010-10-11 23:27
你再试试,不行的话,把表结构发上来,这样大家就可以减少建表的过程了.直接交流,多方便.明天见
#5
上帝之允2010-10-12 12:46
where 修改日期 = (select top 1 修改日期 from 药库 where medician_name=@name order by
修改日期 desc) 我用这句话替换了先前的最后一句,有些改善,可是还是不行,我想问的是这句话可不可以
完成条件是指定药品离现在最近的一条记录
#6
gameohyes2010-10-12 12:59
程序代码:

else //@name in(select medician_name from 药库) 那么应该是更新了吧,不需要再次插入了吧
begin
insert into 药库
select @name,@number+medician_store,date
from inserted,药库
where @name=药库.medician_name and 修改日期=(select top 1
修改日期 from 药库 order by 修改日期 desc)
end
go
#7
上帝之允2010-10-12 13:04
我希望的是插入,不想跟新,可是插入的话一直实现不了
#8
上帝之允2010-10-12 13:09
create table 药库
(
   medician_name varchar(20),
   medician_store int check(medician_store>0),
   修改日期 datetime default getdate()
)
create table 入库清单
(
  medician_name varchar(20),
  medician_norms varchar(20),
  medician_number int,
  medician_unit char(10) default '盒',
  medician_unitprice money,
  medician_totalmoney money,
  date datetime default getdate(),
  businessman char(10),
  P_incharge char(10),
  accountant char(10),
  Y_person char(10),
  J_person char(10)
)

insert into 入库清单  values('感冒冲剂','500g',300,'盒','15.0','4500',getdate(),'刘金宝','李金宝','汤唯','周','蔡')
insert into 药库(medician_name,medician_store)output inserted.* values('感冒冲剂',1000);
insert into 药库 (medician_name,medician_store)output inserted.* values('阿司匹林',500);
insert into 药库 (medician_name,medician_store)output inserted.* values('斯达舒',1500);
insert into 药库(medician_name,medician_store) output inserted.* values('整肠生',1200);
#9
上帝之允2010-10-12 16:05
又使了一下,发现当我将药库中的四项第一次全部同时输入的时候,就会出现插入入库清单的时候,无法成功插入药库中,出现无法选择指定药品离插入时间最近记录
#10
上帝之允2010-10-12 20:28
还有个问题,我想实现插入入库清单,随之药库的数据也随之改变的功能除了触发器,别的可以吗
#11
zhaoyang10082010-10-12 22:04
不把inserted里面的字段富裕变量@name等,直接通过inserted. medician_name 引用试试
#12
上帝之允2010-10-12 22:20
我再试试,但是怎么显示无法绑定由多个部分组成的标识符 "medician.number"。
#13
gameohyes2010-10-12 22:24
回复 9楼 上帝之允
那个的话,是触发器引起的.
改变下顺序应该就可以了.
程序代码:

insert into 药库(medician_name,medician_store)output inserted.* values('感冒冲剂',1000);
insert into 药库 (medician_name,medician_store)output inserted.* values('阿司匹林',500);
insert into 药库 (medician_name,medician_store)output inserted.* values('斯达舒',1500);
insert into 药库(medician_name,medician_store) output inserted.* values('整肠生',1200);
insert into 入库清单  values('感冒冲剂','500g',300,'','15.0','4500',getdate(),'刘金宝','李金宝','汤唯','','')
#14
上帝之允2010-10-12 22:30
是将插入的顺序修改一下吗?? 但是是因为触发器的问题,无法同时插入吗
#15
gameohyes2010-10-12 22:33
这样可以不
程序代码:

if object_id('Trigger1','TR')is not null
drop Trigger Trigger1;
go
create trigger Trigger1 on 入库清单
for insert
as
declare @number int,@name varchar(15);
select @number=medician_number,@name=medician_name from inserted
if(@name not in(select medician_name from 药库))
begin
insert into 药库(medician_name,medician_store,修改日期)
select @name,@number,date
from inserted
end
else
begin
update 药库 set medician_store=medician_store+(select medician_number from inserted),
                修改日期=getdate()        
where medician_name =(select medician_name from inserted )
end
go
#16
上帝之允2010-10-12 22:41
我先开始的初衷用insert不用update是为了,我想查某月某日的库存余量,可是改成update的话,我想不出来怎么做了
#17
gameohyes2010-10-12 22:57
那就这样吧:
程序代码:

if object_id('Trigger1','TR')is not null
drop Trigger Trigger1;
go
create trigger Trigger1 on 入库清单
for insert
as
declare @number int,@name varchar(15);
select @number=medician_number,@name=medician_name from inserted
if(@name not in(select medician_name from 药库))
begin
insert into 药库(medician_name,medician_store,修改日期)
select @name,@number,date
from inserted
end
else
begin
insert into 药库  
select medician_name,medician_number,date from inserted
end
go
#18
上帝之允2010-10-12 23:01
可是这样修改的触发器是将入库清单的数据照搬入药库呀,这样药库就没有意义了,没有办法显示库存了
#19
gameohyes2010-10-12 23:23
程序代码:

if object_id('Trigger1','TR')is not null
drop Trigger Trigger1;
go
create trigger Trigger1 on 入库清单
after insert
as
declare @number int,@name varchar(15);
select @number=medician_number,@name=medician_name from inserted
if(@name not in(select medician_name from 药库))
begin
insert into 药库(medician_name,medician_store,修改日期)
select @name,@number,date
from inserted
end
else
begin
insert into 药库
select @name,@number+medician_store,date
from inserted,药库
where 修改日期 = (select top 1 修改日期 from 药库 where medician_name=@name order by 修改日期 desc)
end
go

引用:
我用这句话替换了先前的最后一句,有些改善,可是还是不行,我想问的是这句话可不可以
完成条件是指定药品离现在最近的一条记录

想达到什么样的目的?
#20
png2010-10-13 02:38
"where 修改日期 = (select top 1 修改日期 from 药库 where medician_name=@name order by
修改日期 desc) 我用这句话替换了先前的最后一句,

有些改善,可是还是不行,  -- 应该可以了.  -- 什么是有些改善,还是不行?


我想问的是这句话可不可以完成条件是指定药品离现在最近的一条记录 -- 可以.


#21
上帝之允2010-10-13 12:34
我现在修改后的触发器,基本可以完成所需的功能,可是唯一的问题是在我第一次输入到药库数据的时候,如果是同时输入的话,触发器就无法分辨我想要的药品,例如进货感冒冲剂300盒,那么所有的药品将都增加300,不知道为什么??
  还有一个问题就是我现在的触发器功能可不可以用其他语句代替,我听说触发器很耗系统的,所以想要问问有没有其他方法?谢谢各位了!!!!
#22
png2010-10-13 21:57
(1) 修改后的触发器版本是什么样的?

(2) ... 可是唯一的问题是在我第一次输入到药库数据的时候,如果是同时输入的话,触发器就无法分辨我想要的药品...

把你的语句贴上来看看?
#23
上帝之允2010-10-13 22:31
create table 药库
(
   medician_name varchar(20),
   medician_store int check(medician_store>0),
   修改日期 datetime default getdate()
)
create table 入库清单
(
  medician_name varchar(20),
  medician_norms varchar(20),
  medician_number int,
  medician_unit char(10) default '盒',
  medician_unitprice money,
  medician_totalmoney money,
  date datetime default getdate(),
  businessman char(10),
  P_incharge char(10),
  accountant char(10),
  Y_person char(10),
  J_person char(10)
)

if object_id('Trigger1','TR')is not null
drop Trigger Trigger1;
go
create trigger Trigger1 on 入库清单
after insert
as
declare @number int,@name varchar(20);
select @number=medician_number,@name=medician_name from inserted
if(@name not in(select medician_name from 药库))
begin
insert into 药库
select @name,@number,date
from inserted
end
else
begin
insert into 药库
select inserted.medician_name,@number+medician_store,date
from inserted,药库
where 修改日期 = (select top 1 修改日期 from 药库 where medician_name=inserted.medician_name
                  order by 修改日期 desc)
end
go

insert into 药库(medician_name,medician_store)output inserted.* values('感冒冲剂',1000);
insert into 药库 (medician_name,medician_store)output inserted.* values('阿司匹林',500);
insert into 药库 (medician_name,medician_store)output inserted.* values('斯达舒',1500);
insert into 药库(medician_name,medician_store) output inserted.* values('整肠生',1200);

insert into 入库清单  values('整肠生','500g',300,'盒','15.0','4500',getdate(),'刘金宝','李金宝','汤','周杰','蔡')
#24
png2010-10-14 00:28
你的 where 语句改得太多了. 将你的一页的语句
...
where @name=药库.medician_name and 修改日期=(select top 1
修改日期 from 药库 order by 修改日期 desc)
...

改成
...
where @name=药库.medician_name and 修改日期=(select top 1
修改日期 from 药库 where medician_name=inserted.medician_name order by 修改日期 desc)
...

看看如何?


1