请教:使用触发器检查新insert插入数据

fengyqf 2013-08-20 02:00:43
现在有一张表,结构如下:

CREATE TABLE [dbo].[tab](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [nvarchar](50) NULL,
[name] [nvarchar](20) NULL,
[time] [datetime] NULL
) ON [PRIMARY]


往这个表里插入数据的程序分散在很多地方。
为了阻止重复的数据插入,准备写一个触发器。
期望是,在插入数据时,检查最新的100条数据里、有多少条重复记录(按title,name两个字段检查重复);如果重复记录超过3条,就不再插入数据。


请问这个触发器怎么写?
谢谢!
...全文
424 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Shawn 2013-08-22
  • 打赏
  • 举报
回复
引用 6 楼 fengyqf 的回复:
[quote=引用 3 楼 wwwwgou 的回复:] 也可以建立一个AFTER类型的触发器,但那么利用的回滚事务的做法。如果INSTEAD OF触发器能满足需要,就不要用AFTER类型的了。
不过after型的有一个好处,给表新增字段后,可以不用修改触发器。 这在频繁修改的应用上会有些优势。毕竟有时修改表结构时会忘掉触发器这茬儿[/quote] #1.触发器没效率,一般生产系统要禁用 #2.AFTER触发器,靠的是事务回滚,也没效率。 #3.要有规范,无论系统结构怎么改。涉及到的更改,都要一起事先考虑好。
fengyqf 2013-08-22
  • 打赏
  • 举报
回复
引用 3 楼 wwwwgou 的回复:
也可以建立一个AFTER类型的触发器,但那么利用的回滚事务的做法。如果INSTEAD OF触发器能满足需要,就不要用AFTER类型的了。
不过after型的有一个好处,给表新增字段后,可以不用修改触发器。 这在频繁修改的应用上会有些优势。毕竟有时修改表结构时会忘掉触发器这茬儿
fengyqf 2013-08-22
  • 打赏
  • 举报
回复
引用 2 楼 wwwwgou 的回复:
CREATE TABLE [dbo].[tab](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [nvarchar](50) NULL,
[name] [nvarchar](20) NULL,
[time] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TRIGGER tr_instead ON dbo.tab
INSTEAD OF INSERT
as
begin
	--在插入数据时,检查最新的100条数据里、有多少条重复记录(按title,name两个字段检查重复);如果重复记录超过3条,就不再插入数据。
	SELECT * FROM INSERTED

	INSERT INTO tab(title, name, [time])
	SELECT I.[title],I.[name], GETDATE()
	FROM INSERTED I
	left JOIN
	(
		SELECT TOP(100) title, name FROM tab WITH(NOLOCK) ORDER BY [time] DESC
	) T
	ON i.title = i.title
		AND I.NAME = T.NAME
	GROUP BY i.title, i.name      
	HAVING COUNT(t.title) < 3
END

GO

INSERT INTO [tab](TITLE,NAME, TIME)
SELECT '1', '1', GETDATE()	--插入3次后,将插入不进去

/*
id	title	name	time
1	1	1	2013-08-20 16:51:20.387
2	1	1	2013-08-20 16:51:25.150
3	1	1	2013-08-20 16:51:34.037
*/
这个写法好,很简洁。我用after写的,用if exists()判断条件,繁琐得多。
百度地图纠偏 2013-08-20
  • 打赏
  • 举报
回复
可以像我请教地图纠偏方面的问题哈
Shawn 2013-08-20
  • 打赏
  • 举报
回复
也可以建立一个AFTER类型的触发器,但那么利用的回滚事务的做法。如果INSTEAD OF触发器能满足需要,就不要用AFTER类型的了。
Shawn 2013-08-20
  • 打赏
  • 举报
回复
CREATE TABLE [dbo].[tab](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [nvarchar](50) NULL,
[name] [nvarchar](20) NULL,
[time] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TRIGGER tr_instead ON dbo.tab
INSTEAD OF INSERT
as
begin
	--在插入数据时,检查最新的100条数据里、有多少条重复记录(按title,name两个字段检查重复);如果重复记录超过3条,就不再插入数据。
	SELECT * FROM INSERTED

	INSERT INTO tab(title, name, [time])
	SELECT I.[title],I.[name], GETDATE()
	FROM INSERTED I
	left JOIN
	(
		SELECT TOP(100) title, name FROM tab WITH(NOLOCK) ORDER BY [time] DESC
	) T
	ON i.title = i.title
		AND I.NAME = T.NAME
	GROUP BY i.title, i.name      
	HAVING COUNT(t.title) < 3
END

GO

INSERT INTO [tab](TITLE,NAME, TIME)
SELECT '1', '1', GETDATE()	--插入3次后,将插入不进去

/*
id	title	name	time
1	1	1	2013-08-20 16:51:20.387
2	1	1	2013-08-20 16:51:25.150
3	1	1	2013-08-20 16:51:34.037
*/
---涛声依旧--- 2013-08-20
  • 打赏
  • 举报
回复
1、为了阻止重复的数据插入————建议设计表的时候建立主键或唯一索引 2、if exists(select 1 from inserted group by title,[name] having count(title)>3) ......

34,588

社区成员

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

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