Sql server 插入触发器工作不正常
我已经在删除的用户表中为insert创建了以下触发器,相应的记录必须从userlogin表中删除 触发器涉及以下语句:Sql server 插入触发器工作不正常,sql-server,Sql Server,我已经在删除的用户表中为insert创建了以下触发器,相应的记录必须从userlogin表中删除 触发器涉及以下语句: CREATE TRIGGER trgInsert_ToDeleteFromUserLogin on DELETEDUSER FOR INSERT AS BEGIN DECLARE @UserName nvarchar(50), @UserType nvarchar(30), @Reason nvarchar(max) SELECT @UserName = USERNAME
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表中删除(删除)该行
提前谢谢 为什么要在DeletedUser上的插入触发器中插入DeletedUser?这已经发生了,因为这正是最初触发的原因。删除该部分,它应该是好的。您的触发器是“后”触发器(默认值),而不是“代替”。使用AFTER触发器时,“契约已经完成”——也就是说,DeletedUser中的insert已经发生,因此您不需要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
假设插入的表中只有一行,则会写入触发器。SQL没有行触发器(就像Oracle一样),它的触发器对一条语句触发一次,插入/删除的表将包含受该语句影响的所有行 选择@UserName=UserName,@UserType =用户类型,@Reason=插入的原因 如果在一条语句中插入4行,这里会发生什么 除了前面的回复中注意到的问题外,还需要对触发器进行编码,以便它能够处理插入表中的任意数量的行
为了更好地介绍SQL中的触发器,请阅读以下内容:为什么要在特殊表中使用insert来删除用户?如果您需要跟踪删除,则在UserLogin上放置一个delete触发器以记录更改更为合理。Sheetal,还请注意RicharTallent已将触发器写入以处理多行。SQL Server触发器是每个语句,而不是每行。