2014-08-29 25 views
10

Tôi gặp sự cố với trình kích hoạt này. Tôi muốn nó cập nhật thông tin được yêu cầu chỉ cho hàng được đề cập (hàng tôi vừa cập nhật) chứ không phải toàn bộ bảng.Máy chủ SQL sau khi kích hoạt cập nhật

CREATE TRIGGER [dbo].[after_update] 
    ON [dbo].[MYTABLE] 
    AFTER UPDATE 
    AS 
    BEGIN 
      UPDATE MYTABLE 
      SET mytable.CHANGED_ON = GETDATE(), 
      CHANGED_BY=USER_NAME(USER_ID()) 

Làm cách nào để cho biết trình kích hoạt chỉ áp dụng cho hàng được đề cập?

+2

Chỉ cần thêm một tham gia vào bảng chèn vào trong báo cáo cập nhật của bạn dựa trên khóa chính. –

+0

đã thêm một kết nối nhưng kích hoạt của tôi cũng kích hoạt. Đây có phải là hành vi bình thường hay không? – user3927897

Trả lời

0

Bạn sẽ có thể truy cập vào bảng INSERTED và truy xuất ID hoặc khóa chính của bảng. Một cái gì đó tương tự như ví dụ này ...

CREATE TRIGGER [dbo].[after_update] ON [dbo].[MYTABLE] 
AFTER UPDATE AS 
BEGIN 
    DECLARE @id AS INT 
    SELECT @id = [IdColumnName] 
    FROM INSERTED 

    UPDATE MYTABLE 
    SET mytable.CHANGED_ON = GETDATE(), 
    CHANGED_BY=USER_NAME(USER_ID()) 
    WHERE [IdColumnName] = @id 

Dưới đây là một liên kết trên MSDN trên INSERTEDDELETED bảng có sẵn khi sử dụng trigger: http://msdn.microsoft.com/en-au/library/ms191300.aspx

+2

Kane, điều này không đúng nếu nhiều hàng được cập nhật vì giá trị vô hướng sẽ chỉ được đặt cho hàng cuối cùng trong tập hợp và bỏ lỡ tất cả các hàng khác. –

+0

@SeanGallardy, ahh có bạn là chính xác. Tôi đã giả định rằng chỉ có 1 hàng được cập nhật.Bạn biết họ nói gì về các giả định. – Kane

+3

Với trình kích hoạt, bạn nên LUÔN LUÔN giả sử có nhiều hàng bị ảnh hưởng. –

0

Trước hết, kích hoạt của bạn như bạn đã thấy sẽ cập nhật mỗi ghi lại trong bảng. Không có lọc được thực hiện để thực hiện các jus các hàng thay đổi.

Thứ hai, bạn giả định rằng chỉ có một hàng thay đổi trong lô không chính xác vì nhiều hàng có thể thay đổi.

Cách để làm điều này đúng là sử dụng chèn và xóa bảng ảo: http://msdn.microsoft.com/en-us/library/ms191300.aspx

+0

Đã thêm: FROM dbo.mytable INNER JOIN được chèn ON mytable.TW_ID = inserted.TW_ID Tại sao kích hoạt kích hoạt sau khi chèn sự kiện? – user3927897

-1
CREATE TRIGGER [dbo].[after_update] ON [dbo].[MYTABLE] 
AFTER UPDATE 
AS 
BEGIN 
    DECLARE @ID INT 

    SELECT @ID = D.ID 
    FROM inserted D 

    UPDATE MYTABLE 
    SET mytable.CHANGED_ON = GETDATE() 
     ,CHANGED_BY = USER_NAME(USER_ID()) 
    WHERE ID = @ID 
END 
+2

Loại trình kích hoạt này sẽ không xử lý nhiều hoạt động của hàng. Nếu có nhiều hơn 1 hàng được cập nhật thì điều này sẽ không hoạt động chính xác. –

10

Dưới đây là ví dụ của tôi sau một thử nghiệm

CREATE TRIGGER [dbo].UpdateTasadoresName 
ON [dbo].Tasadores 
FOR UPDATE 
AS 
     UPDATE Tasadores 
     SET NombreCompleto = RTRIM(Tasadores.Nombre + ' ' + isnull(Tasadores.ApellidoPaterno,'') + ' ' + isnull(Tasadores.ApellidoMaterno,'') ) 
     FROM Tasadores 
    INNER JOIN INSERTED i ON Tasadores.id = i.id 

Các chèn bảng đặc biệt sẽ có thông tin từ bản ghi được cập nhật.

3

Hãy thử điều này (cập nhật, không phải sau khi cập nhật)

CREATE TRIGGER [dbo].[xxx_update] ON [dbo].[MYTABLE] 
    FOR UPDATE 
    AS 
    BEGIN 

     UPDATE MYTABLE 
     SET mytable.CHANGED_ON = GETDATE() 
      ,CHANGED_BY = USER_NAME(USER_ID()) 
     FROM inserted 
     WHERE MYTABLE.ID = inserted.ID 

    END 
+0

ĐỂ CẬP NHẬT và SAU KHI CẬP NHẬT giống hệt nhau, cả hai đều kích hoạt sau khi cập nhật đã xảy ra và đã được cam kết. Bảng được chèn giữ tất cả các bản ghi được sửa đổi, như bạn đã lưu ý chính xác. – kuklei

3

Nó rất đơn giản để làm điều đó, Đầu tiên tạo ra một bản sao của bảng của bạn mà muốn bạn giữ các bản ghi cho Ví dụ, bạn có Bảng dbo .SalesOrder với các cột SalesOrderID, FirstName, LastName, LastModified

bảng Version Archieve của bạn nên được dbo.SalesOrderVersionArchieve với các cột SalesOrderVersionArhieveId, SalesOrderID, FirstName, LastName, LastModified

Dưới đây là làm thế nào bạn sẽ thiết lập kích hoạt trên bàn SalesOrder

USE [YOURDB] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  Karan Dhanu 
-- Create date: <Create Date,,> 
-- Description: <Description,,> 
-- ============================================= 
CREATE TRIGGER dbo.[CreateVersionArchiveRow] 
    ON dbo.[SalesOrder] 
    AFTER Update 
AS 
BEGIN 

    SET NOCOUNT ON; 
INSERT INTO dbo.SalesOrderVersionArchive 

    SELECT * 
    FROM deleted; 

END 

Bây giờ nếu bạn thực hiện bất kỳ thay đổi trong bảng saleOrder nó sẽ cho bạn thấy sự thay đổi trong VersionArchieve bảng

+0

thx để giải thích đơn giản nhưng hiệu quả – Daidon

1

thử giải pháp này.

DECLARE @Id INT 
    DECLARE @field VARCHAR(50) 

    SELECT @Id= INSERTED.CustomerId  
    FROM INSERTED 

    IF UPDATE(Name) 
    BEGIN 
      SET @field = 'Updated Name' 
    END 

    IF UPDATE(Country) 
    BEGIN 
      SET @field = 'Updated Country' 
    END 

    INSERT INTO CustomerLogs 
    VALUES(@Id, @field) 

tôi không kiểm tra này với phiên bản cũ của máy chủ sql nhưng điều này sẽ làm việc với máy chủ sql 2012.

Các vấn đề liên quan