我在已删除的用户表中创建了以下触发器,必须从userlogin表中删除相应的记录。
触发器涉及以下声明:
CREATE TRIGGER trgInsert_ToDeleteFromUserLogin on DELETEDUSER
FOR INSERT
AS
BEGIN
DECLARE
@UserName nvarchar(50),
@UserType nvarchar(30),
@Reason nvarchar(max)
SELECT @UserName = USERNAME, @UserType = UserType, @Reason = Reason FROM INSERTED
INSERT INTO DELETEDUSER (USERNAME,USERTYPE,REASON) VALUES(@USERNAME,@USERTYPE,@REASON)
DELETE FROM USERLOGIN WHERE USERNAME = @UserName
end
但是当我在deleteduser表中插入记录时,相应的记录将从userlogin表中删除,但不会插入到deleteduser表中。
上述触发器不会产生任何错误,但是当我尝试在已删除的用户表中插入记录时,我注意到该记录已从UserLogin表中删除,但同样没有插入DeletedUser表中。
供您参考我包括deleteduser和userlogin的表结构如下:
Deleted User
CREATE TABLE DELETEDUSER
(
DeletedUserID int identity(1,1),
UserName nvarchar(max),
UserType nvarchar(30),
Reason nvarchar(max)
)
--ALTERING DELETEDUSER TABLE TO SPECIFY THE SIZE OF USERNAME COLUMN FOR IMPOSING FOREIGN KEY CONSTRAINT
ALTER TABLE DELETEDUSER ALTER COLUMN UserName nvarchar(50)
--ALTERING DELETEDUSER TABLE TO ADD FOREIGN KEY CONSTRAINT
ALTER TABLE DELETEDUSER ADD CONSTRAINT fk_UserName Foreign key (UserName) references UserLogin(UserName) on delete cascade
USERLOGIN TABLE:
CREATE TABLE USERLOGIN
(
UserID int identity(1,1) not null,
UserName nvarchar(50) not null,
Password nvarchar(50) not null
)
--ALTER TABLE USERREGISTRATION TO ADD PRIMARYKEY
ALTER TABLE USERLOGIN ADD CONSTRAINT pk_UserName primary key(UserName)
请帮我修改我应该在deleteduser表中插入行并从userlogin表中删除(删除)它。
提前致谢!
答案 0 :(得分:2)
您的触发器是“AFTER”触发器(默认值),而不是“INSTEAD OF”。使用AFTER触发器,“契约已经完成” - 即插入DeletedUser已经发生,所以你不需要INSERT语句。
DeletedUser和UserLogin之间的外键关系完全错误。根据您的描述,这些表是互斥的:在DeletedUser中拥有一个用户意味着他们不应再在UserLogin中,并且让用户在UserLogin中意味着他们也不会是DeletedUser。
所以,删除外键关系,试试这个:
CREATE TRIGGER trgInsert_ToDeleteFromUserLogin on DELETEDUSER FOR INSERT AS
BEGIN
DELETE FROM UserLogin WHERE EXISTS (SELECT NULL FROM INSERTED WHERE
INSERTED.USERNAME = UserLogin.USERNAME)
END
编辑:正如Shannon在下面提到的,这个代码将正确处理同时插入多个记录的情况,这与原始代码的单行假设形成对比。用例(禁用用户)一次只建议一个插入,但构建触发器对插入/删除的元表中的整个记录集进行操作会更好(也更容易)。
另外,通过使用视图可以简化数据库设计。例如:
ALTER TABLE UserLogin ADD DeletedReason varchar(255) NULL
CREATE VIEW ActiveUser AS SELECT * FROM UserLogin WHERE DeletedReason IS NULL
答案 1 :(得分:0)
为什么要在DeletedUser的INSERT触发器中插入DeletedUser?这已经发生了,因为这首先触发了触发器。删除那部分它应该没问题。
答案 2 :(得分:0)
假设插入的表中只有一行,则会写入您的触发器。 SQL没有行触发器(就像Oracle那样),它的触发器为一个语句触发一次,插入/删除的表将包含受语句影响的所有行
SELECT @UserName = USERNAME,@ UserType = UserType,@ Reason = Reason FROM INSERTED
如果在一个语句中插入4行,会发生什么?
除了早期回复中注意到的问题之外,您还需要对触发器进行编码,以便它可以处理插入表中的任意数量的行。
有关SQL中触发器的详细介绍,请阅读:http://www.sqlservercentral.com/articles/Triggers/64214/