请大手救急!怎样将数据库表中某列符合查询条件的字段值自动加1或减1?

saucerman 2000-06-01 03:33:00
有一网站新闻发布表news,按如下建表命令建立:

create table news
(auto_id int identity(1,1) constraint PK_news primary key clustered,
pub_time datetime default getdate(),
title varchar(80),
detail text,
news_id int default 0,
keepdays int default 1)

auto_id是自增加的新闻流水号
pub_time是新闻发布时间,默认取加入记录时的系统时间
title是新闻标题
detail是新闻细节
news_id是新闻发表的排列顺序号,缺省值为0
keepdays是新闻在发布版面上的保留天数,缺省值为1

现于news表的insert上建一触发器,如下:

CREATE TRIGGER trg_PublishNews_t ON dbo.news_t
FOR INSERT
AS
declare @curdate int
declare @maxdate int
set @curdate=convert(int,getdate(),112)
set @maxdate=convert(int,getdate()-(select pub_time from news_t where auto_id=(select max(auto_id) from news_t)),112)
if(@curdate>@maxdate)
begin
update news_t set keepdays=keepdays-1 where keepdays>0
end
update news_t set news_id=news_id+1 where news_id<>0
update news_t set news_id=1 from inserted

上面的触发器主要想达到的效果是,在插入时,将原来的新闻发布号自动加1,
即向下滚动。新插的这条记录的新闻发布号news_id置1(放在最前边)。
再看看日期是否正好变为下一天,
如果是,就将保留天数自动减1(为0则不减)。

但上边的Trigger有错,不能实现相应的功能!

请各位高手惠赐妙招!多谢!感激不尽!涕泪横流,哗哗地!!!
...全文
1070 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
tanghuan 2000-06-02
  • 打赏
  • 举报
回复
as 是可以省去的呀

例如 select * from (select 1 aa ) a
zy 2000-06-02
  • 打赏
  • 举报
回复
update news set news_id=temp.new_id
from news,(select a.id,count(*) as new_id /*反方向按ID排序生成序号*/
from news a , news b
where news.id<=b.id
group by a.id) temp //应为group by a.id) as temp
where news.id=temp.id


tanghuan 2000-06-02
  • 打赏
  • 举报
回复
CREATE TRIGGER trg_PublishNews ON dbo.news
FOR INSERT
AS

declare @curdate int
declare @maxdate int,
@RelativeDay int /*日期差*/
set @curdate=convert(int,getdate(),112)
select @maxdate=convert(int,(select max(pub_time) /*获取非正在插入的行的最大时间*/
from News
where id not in (select id
from inserted

)
)
,112
)

select @RelativeDay =@curdate-@maxdate /*如果相隔多天*/

update news set news_id=temp.new_id
from news,(select a.id,count(*) as new_id /*反方向按ID排序生成序号*/
from news a , news b
where news.id<=b.id
group by a.id) temp
where news.id=temp.id


if(@RelativeDay >0)
begin
update news set keepdays=(case
when keepdays-@RelativeDay >=0
then keepdays-@RelativeDay
else 0
end)
where keepdays>0
end

saucerman 2000-06-02
  • 打赏
  • 举报
回复
有一网站新闻发布表news,按如下建表命令建立:

create table news
(auto_id int identity(1,1) constraint PK_news primary key clustered,
pub_time datetime default getdate(),
title varchar(80),
detail text,
news_id int default 0,
keepdays int default 1)

auto_id是自增加的新闻流水号
pub_time是新闻发布时间,默认取加入记录时的系统时间
title是新闻标题
detail是新闻细节
news_id是新闻发表的排列顺序号,缺省值为0
keepdays是新闻在发布版面上的保留天数,缺省值为1

现于news表的insert上建一触发器,如下:

CREATE TRIGGER trg_PublishNews ON dbo.news
FOR INSERT
AS

update news_t set news_id=news_id+1 where news_id<>0
update news_t set news_id=1 from inserted

/*
declare @curdate int
declare @maxdate int
set @curdate=convert(int,getdate(),112)
set @maxdate=convert(int,
(select pub_time from News
where auto_id=(select max(auto_id) from news)),112)

if(@curdate>@maxdate)
begin
update news set keepdays=keepdays-1 where keepdays>0
end
*/

上面的触发器主要想达到的效果是,在插入时,将原来的新闻发布号自动加1,
即向下滚动。新插的这条记录的新闻发布号news_id置1(放在最前边)。
再看看日期是否正好变为下一天,
如果是,就将保留天数自动减1(为0则不减)。

但上边的Trigger有错,不能实现相应的功能!

请各位高手惠赐妙招!


saucerman 2000-06-02
  • 打赏
  • 举报
回复
以上是完整的Trigger建立语句!
saucerman 2000-06-02
  • 打赏
  • 举报
回复
CREATE TRIGGER trg_PublishNews ON dbo.news
FOR INSERT
AS

declare @curdate int
declare @maxdate int,
@RelativeDay int --日期差
set @curdate=convert(int,getdate(),112)
select @maxdate=convert(int,(select max(pub_time)
from News
where auto_id not in (select auto_id
from inserted)),112)
--获取非正在插入的行的最大时间

select @RelativeDay =@curdate-@maxdate
--如果相隔多天,比如星期五录后,隔周末星期一再录



update news set news_id=tmp.new_id
from news,(select a.auto_id,count(*) as new_id
from news a,news b
where a.auto_id<=b.auto_id
group by a.auto_id) tmp
where news.auto_id=tmp.auto_id
--反方向按ID排序生成序号

if(@RelativeDay >0)
begin
update news set keepdays=(case
when keepdays-@RelativeDay >=0
then keepdays-@RelativeDay
else 0
end)
where keepdays>0
end
zy 2000-06-02
  • 打赏
  • 举报
回复
谢谢tanghuan,你的回答中有一技术点,帮我解决了一个曾困扰我的问题。
至于as的问题,我用的是MSSQLServer7,不加as会报错。所以有此画蛇添足,抱歉。
saucerman 2000-06-02
  • 打赏
  • 举报
回复
To zy:

其实tanghuan没错,你的也可以(不过有点画蛇添足),用as当然没事,不用也照样。
tanghuan大侠只不过是将查询的结果集赋个别名temp,这一端是没错的。
不过真有个地方有错,可能是tanghuan匆忙中弄错的——
就是 where news.id<=b.id 应为——
where a.id<=b.id
不过小疵不掩大瑕,深谢tanghuan、Axiong、zy及其他大侠!
尤其要感谢tanghuan大侠!

我的这个问题已结束,但现在还有新的需求——
就是个别新闻要始终保持在他的发布位置一端时间——

比如:title为“中欧达成WTO协议”的新闻比较重要——
我要让它的新闻发布号news_id始终是2,在此位置保留3天,即今、明、后天三天。

我想可能必须再增加两个字段 keepnum(保留固定在哪个新闻发布号)
及keepdays(保留天数)。不过,我想主要问题都解决了,应该没什么了。
如果还有其他问题,我会另粘帖子找各位大手帮忙的!

先晾一会儿,我就马上打分了!

那位大侠还有要嘱咐我的,请讲!

再次深谢tanghuan大侠等各位拔刀相助!

saucerman 2000-06-01
  • 打赏
  • 举报
回复
更正——
set @maxdate=convert(int,(select pub_time from News
where id=(select max(id) from news)),112)
应为——
set @maxdate=convert(int,(select pub_time from News
where auto_id=(select max(auto_id) from news)),112)

由于我同时在几个表里试验,难免有不一致的地方!

不过就是——

CREATE TRIGGER trg_PublishNews ON dbo.news
FOR INSERT
AS

update news set news_id=news_id+1 where news_id<>0
update news set news_id=1 from inserted

这样的简单的不带条件的Trigger通过了也行啊!
所有的作用都在这张表上,误为news_t,其实也是news表!
saucerman 2000-06-01
  • 打赏
  • 举报
回复
致tanghuan:

多谢相助!

1。可能您说的“我的触发器好象只能针对每次一条,如果每次多条,触发器要修改”
缺实是对的,请问如何修改?

2。这个错误确实是这样!现改正如下:

CREATE TRIGGER trg_PublishNews ON dbo.news
FOR INSERT
AS

declare @curdate int
declare @maxdate int
set @curdate=convert(int,getdate(),112)
set @maxdate=convert(int,(select pub_time from News
where id=(select max(id) from news)),112)

update news_t set news_id=news_id+1 where news_id<>0
update news_t set news_id=1 from inserted

if(@curdate>@maxdate)
begin
update news_t set keepdays=keepdays-1 where keepdays>0
end

我的数据库问题就在此表,请参照我的上面建表说明!

3。请不考虑条件,上面的

update news_t set news_id=news_id+1 where news_id<>0
update news_t set news_id=1 from inserted

在每插入记录时,也不起作用——

即不能将原来的新闻发布号new_id自动加1!

再请大侠相助!今晚我搞不完就很难回去睡觉!
我现在头脑已混烂不堪!再请高手不吝赐教!
tanghuan 2000-06-01
  • 打赏
  • 举报
回复
1。你的触发器好象只能针对每次一条,如果每次多条,你的触发器要修改

2。set @maxdate=convert(int,getdate()-(select pub_time from news_t where auto_id=(select max(auto_id) from news_t)),112),表达式好象有错,日期型不能做减法吧,我不清楚你的数据库系统,如果这样可以执行,则@maxdate几乎是计算机可以表示的最小时间

如果是set @maxdate=convert(int,(select pub_time from news_t where auto_id=(select max(auto_id) from news_t)),112)的话,当触发器运行时,你的数据已经加入到表中了,所以max(auto_id) 就是你的最新数据的时间,@maxdate几乎等于getdate()(因为加入数据到引起触发器工作几乎是同时的(@curdate>@maxdate)就完全成立,

saucerman 2000-06-01
  • 打赏
  • 举报
回复
致Axiong:

if(@curdate>@maxdate)怎么会是永远都成立的呢?
我的原意是——

如果当前系统时间值(即getdate()取出的值)比较自动流水号对应的最后一条记录值,
也就是上一次最后录入的记录所记入的新闻发布时间pub_time,如果比它大,就说明
新换了日期——

比如上次最后记入的auto_id是45,在已有记录中最大,新闻发布时间pub_time是20000601(2000年6月1号)
现在又加一条新记录——
自动产生的auto_id是46,getdate()取出的值变为了20000602(2000年6月2号)
这时if(@curdate>@maxdate)就应成立!

另外,我还要实现检查new_id不能重复的功能,不知如何做?

多谢相助!

Axiong 2000-06-01
  • 打赏
  • 举报
回复
set @curdate=convert(int,getdate(),112)
set @maxdate=convert(int,getdate()-(select pub_time from news_t where auto_id=(select max(auto_id) from news_t)),112)
if(@curdate>@maxdate)

好象永远都成立的呀。是不是你的判断有问题。

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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