用触发器(trigger)阻止更新(update)表中的某一栏

qq_14976729 2015-10-02 05:56:22
这是原表
C1 C2 C3
NULL 10 1
30 NULL 2
20 20 3

要求用instead of trigger 阻止C3这一栏的任何更新,其他的允许。

以前都是当值大于或小于特定的数就触发,但是这道题要求触发当更新C3中的任何一个。

求教~
...全文
1345 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
misterliwei 2015-10-03
  • 打赏
  • 举报
回复
数据表加一个ID列。

IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE ta
GO
CREATE TABLE TA(ID INT IDENTITY(1,1) PRIMARY KEY, C1 INT, C2 INT, C3 INT)
GO
INSERT INTO TA  VALUES(NULL, 10, 1)
INSERT INTO TA VALUES(30, NULL, 2)
INSERT INTO TA VALUES(20, 20, 3)
GO
SELECT * FROM TA 
GO
IF OBJECT_ID('TRI_TA') IS NOT NULL
DROP TRIGGER TRI_TA
GO
CREATE TRIGGER TRI_TA
ON TA
INSTEAD OF UPDATE 
AS 
  UPDATE TA 
  SET C1 = A.C1 , C2 = A.C2
  FROM TA 
  JOIN inserted  A
  ON TA.ID = A.ID 
GO

UPDATE  TA
SET C1 = 23, C2 = 32, C3 = 99
where ID = 2

SELECT * FROM TA  



  • 打赏
  • 举报
回复
引用 4 楼 qq_14976729 的回复:
[quote=引用 2 楼 misterliwei 的回复:] 数据表加一个ID列。

IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE ta
GO
CREATE TABLE TA(ID INT IDENTITY(1,1) PRIMARY KEY, C1 INT, C2 INT, C3 INT)
GO
INSERT INTO TA  VALUES(NULL, 10, 1)
INSERT INTO TA VALUES(30, NULL, 2)
INSERT INTO TA VALUES(20, 20, 3)
GO
SELECT * FROM TA 
GO
IF OBJECT_ID('TRI_TA') IS NOT NULL
DROP TRIGGER TRI_TA
GO
CREATE TRIGGER TRI_TA
ON TA
INSTEAD OF UPDATE 
AS 
  UPDATE TA 
  SET C1 = A.C1 , C2 = A.C2
  FROM TA 
  JOIN inserted  A
  ON TA.ID = A.ID 
GO

UPDATE  TA
SET C1 = 23, C2 = 32, C3 = 99
where ID = 2

SELECT * FROM TA  



谢谢大神,这个管用。能否问问, 1. 能不能不用到join 和不加ID呢? 2. 你的代码没有提到C3是不是就不能updateC3?而一楼那位朋友为什么只提了C3反而实际上所有update都被禁止了? 不好意思,强迫症犯了。。。~~~[/quote] 1、可以用join语句,不加id。 CREATE TRIGGER TRI_TA ON TA for UPDATE AS if exists(select * from FROM TA JOIN inserted A ON isnull(TA.c1,0) = isnull(A.c1,0) and isnull(ta.c2,0) = isnull(a.c2,0) and isnull(ta.c3,0) <> isnull(a.c3,0)) GO 2、你说的确实是个问题,我觉得之所以用了updated函数来判断有问题,是由于 当你更新其他字段,而不是c3字段的时候,实际上数据库内部也会连带的更新c3,虽然c3的值是没有变化的。
misterliwei 2015-10-03
  • 打赏
  • 举报
回复
引用 4 楼 qq_14976729 的回复:
[quote=引用 2 楼 misterliwei 的回复:] 数据表加一个ID列。

IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE ta
GO
CREATE TABLE TA(ID INT IDENTITY(1,1) PRIMARY KEY, C1 INT, C2 INT, C3 INT)
GO
INSERT INTO TA  VALUES(NULL, 10, 1)
INSERT INTO TA VALUES(30, NULL, 2)
INSERT INTO TA VALUES(20, 20, 3)
GO
SELECT * FROM TA 
GO
IF OBJECT_ID('TRI_TA') IS NOT NULL
DROP TRIGGER TRI_TA
GO
CREATE TRIGGER TRI_TA
ON TA
INSTEAD OF UPDATE 
AS 
  UPDATE TA 
  SET C1 = A.C1 , C2 = A.C2
  FROM TA 
  JOIN inserted  A
  ON TA.ID = A.ID 
GO

UPDATE  TA
SET C1 = 23, C2 = 32, C3 = 99
where ID = 2

SELECT * FROM TA  



谢谢大神,这个管用。能否问问, 1. 能不能不用到join 和不加ID呢? 2. 你的代码没有提到C3是不是就不能updateC3?而一楼那位朋友为什么只提了C3反而实际上所有update都被禁止了? 不好意思,强迫症犯了。。。~~~[/quote] 回答:1.我认为必须添加。因为INSTEAD OF触发器中需要写出自己的UPDATE语句。而缺少JOIN和ID是没办法的。 2.一楼朋友是AFTER触发器,他使用ROLLBACK回滚整个事务,所以所有的UPDATE都回滚了。
qq_14976729 2015-10-03
  • 打赏
  • 举报
回复
引用 2 楼 misterliwei 的回复:
数据表加一个ID列。

IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE ta
GO
CREATE TABLE TA(ID INT IDENTITY(1,1) PRIMARY KEY, C1 INT, C2 INT, C3 INT)
GO
INSERT INTO TA  VALUES(NULL, 10, 1)
INSERT INTO TA VALUES(30, NULL, 2)
INSERT INTO TA VALUES(20, 20, 3)
GO
SELECT * FROM TA 
GO
IF OBJECT_ID('TRI_TA') IS NOT NULL
DROP TRIGGER TRI_TA
GO
CREATE TRIGGER TRI_TA
ON TA
INSTEAD OF UPDATE 
AS 
  UPDATE TA 
  SET C1 = A.C1 , C2 = A.C2
  FROM TA 
  JOIN inserted  A
  ON TA.ID = A.ID 
GO

UPDATE  TA
SET C1 = 23, C2 = 32, C3 = 99
where ID = 2

SELECT * FROM TA  



谢谢大神,这个管用。能否问问, 1. 能不能不用到join 和不加ID呢? 2. 你的代码没有提到C3是不是就不能updateC3?而一楼那位朋友为什么只提了C3反而实际上所有update都被禁止了? 不好意思,强迫症犯了。。。~~~
qq_14976729 2015-10-03
  • 打赏
  • 举报
回复
引用 1 楼 yupeigu 的回复:
创建触发器: create trigger dbo.tri_tb on tb for update as if updated(c3) rollback go
谢谢,我试过了,这个trigger确实在update C1 C2 会显示1 row affected, 在update C3 会触发trigger。但是当你update C1或者C2后,你 select * from 原table,你会发现什么都没有变。就是说虽然这个trigger表面上作用了,但是实际上没有。。。这是为什么。。。。
  • 打赏
  • 举报
回复
创建触发器: create trigger dbo.tri_tb on tb for update as if updated(c3) rollback go

27,579

社区成员

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

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