Sql-Server

在 sql server 上更新觸發器之前

  • January 29, 2022

我有兩個名為usersand的表formerpasswords。在users我有兩個領域:name這是primary keypassword。在formerpasswords我有三個欄位:numberprimary 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

引用自:https://dba.stackexchange.com/questions/264131