Sql-Server
在 sql server 上更新觸發器之前
我有兩個名為
users
and的表formerpasswords
。在users
我有兩個領域:name
這是primary key
和password
。在formerpasswords
我有三個欄位:number
即primary key
和。我想在表上創建一個觸發器,所以如果我在表和欄位中插入一對值,並且在我更新欄位的值之後=我在表中所做的一些插入,觸發器會觸發並插入和的舊值桌子。我怎麼能在 SQL Server 中做到這一點?我知道這可以很容易地在 MySQL 中使用但在不存在的 SQL Server 中完成,所以我尋找一種方法來做到這一點。name``password``users``users``name``password``password``name``users``name``password``formerpasswords``before update trigger
非常感謝你。
這是一個功能性(儘管是基本的)範例。SQL Server 中的觸發器可以是 AFTER 或 INSTEAD,並且可以應用於任何 DML(INSERT、UPDATE 或 DELETE),甚至可以同時應用。每個觸發器的範圍內都有一個虛擬表,稱為:
- 插入 - 打算成為什麼。
- 已刪除 - 舊值是什麼。
這些虛擬表包含基表中的每一列,並對基表或其他表進行修改。
注意事項(或基本提醒):
- 確保觸發器內的語句可以正確處理多行。我看到的一個常見錯誤是人們使觸發器內的邏輯一次只能用於一行。
- 這些會降低性能,謹慎使用它們並保持邏輯盡可能簡單。
- 批量插入通常不會觸發觸發器,但可以配置為這樣做。
- 避免在觸發器內使用游標。
- 您不能在觸發器內嘗試/擷取。那裡發生的任何異常都會冒泡給呼叫者。
最後
注意使用適當的密碼庫儲存密碼。我在下面的範例中使用了 VARCHAR 來更好地說明觸發邏輯。
DROP TABLE IF EXISTS dbo.FormerPasswords DROP TABLE IF EXISTS dbo.Users GO CREATE TABLE dbo.Users ( UsersID INT NOT NULL IDENTITY(1,1) PRIMARY KEY , UserName NVARCHAR(200) NOT NULL , CurrentPassword VARCHAR(64) NOT NULL ) CREATE TABLE dbo.FormerPasswords ( FormerPasswords INT NOT NULL IDENTITY(1,1) PRIMARY KEY , UsersID INT NOT NULL REFERENCES dbo.Users (UsersID) , PriorPasswords VARCHAR(64) NOT NULL , DateLastUsed_UTC DATETIME2(7) NOT NULL DEFAULT (SYSUTCDATETIME()) ) GO CREATE OR ALTER TRIGGER trgUsers ON dbo.Users AFTER UPDATE AS BEGIN INSERT INTO dbo.FormerPasswords (UsersID, PriorPasswords) SELECT D.UsersID , D.CurrentPassword FROM DELETED AS D END GO INSERT INTO dbo.Users (UserName, CurrentPassword) VALUES ('jsmith', 'original 1') , ('jdoe', 'original 2') UPDATE dbo.Users SET CurrentPassword = 'updated 1' WHERE UserName = 'jsmith' SELECT * FROM dbo.Users SELECT * FROM dbo.FormerPasswords
嘗試這樣的事情:
alter trigger demotrigger on table1 for update as begin select * into #tmp from deleted; insert into table2 select * from #tmp where #tmp.name not in (select name from table2) update table2 set oldpass=#tmp.pass from #tmp join table2 on table2.name=#tmp.name drop table #tmp; end