inserted 및 deleted 테이블 사용Use the inserted and deleted Tables

DML 트리거 문은 두 개의 특수 테이블(inserted 및 deleted 테이블)을 사용합니다.DML trigger statements use two special tables: the deleted table and the inserted tables. SQL ServerSQL Server 에서는 이러한 테이블을 자동으로 만들고 관리합니다. automatically creates and manages these tables. 메모리에 상주하는 이러한 임시 테이블을 사용하여 특정 데이터의 수정 결과를 테스트하고 DML 트리거 동작에 대한 조건을 설정할 수 있습니다.You can use these temporary, memory-resident tables to test the effects of certain data modifications and to set conditions for DML trigger actions. 이 테이블에서 데이터를 직접 수정하거나 CREATE INDEX와 같은 DDL(데이터 정의 언어) 작업을 수행할 수 없습니다.You cannot directly modify the data in the tables or perform data definition language (DDL) operations on the tables, such as CREATE INDEX.

DML 트리거에서 inserted 및 deleted 테이블은 주로 다음 작업을 수행하는 데 사용됩니다.In DML triggers, the inserted and deleted tables are primarily used to perform the following:

  • 테이블 간 참조 무결성을 확장합니다.Extend referential integrity between tables.

  • 뷰를 원본으로 사용하는 기본 테이블에 데이터를 삽입하거나 업데이트합니다.Insert or update data in base tables underlying a view.

  • 오류가 있는지 테스트하고 오류에 따른 적절한 동작을 수행합니다.Test for errors and take action based on the error.

  • 데이터를 수정하기 전과 후의 테이블 상태 차이를 찾고 이 차이에 따라 동작을 수행합니다.Find the difference between the state of a table before and after a data modification and take actions based on that difference.

    deleted 테이블에는 DELETE 및 UPDATE 문을 실행할 때 영향을 받는 행의 복사본이 저장됩니다.The deleted table stores copies of the affected rows during DELETE and UPDATE statements. DELETE 또는 UPDATE 문을 실행하는 동안 트리거 테이블에서 행이 삭제되어 deleted 테이블로 이동됩니다.During the execution of a DELETE or UPDATE statement, rows are deleted from the trigger table and transferred to the deleted table. deleted 테이블과 트리거 테이블은 보통 서로 공통되는 행이 없습니다.The deleted table and the trigger table ordinarily have no rows in common.

    inserted 테이블에는 INSERT 및 UPDATE 문을 실행할 때 영향을 받는 행의 복사본이 저장됩니다.The inserted table stores copies of the affected rows during INSERT and UPDATE statements. 삽입 또는 업데이트 트랜잭션 동안 새 행은 inserted 테이블과 트리거 테이블에 추가됩니다.During an insert or update transaction, new rows are added to both the inserted table and the trigger table. inserted 테이블의 행은 트리거 테이블에 있는 새 행의 복사본입니다.The rows in the inserted table are copies of the new rows in the trigger table.

    업데이트 트랜잭션은 삭제 작업과 삽입 작업을 차례로 수행하는 것과 비슷합니다. 즉 이전 행이 먼저 deleted 테이블로 복사된 다음 새 행이 트리거 테이블과 inserted 테이블로 복사됩니다.An update transaction is similar to a delete operation followed by an insert operation; the old rows are copied to the deleted table first, and then the new rows are copied to the trigger table and to the inserted table.

    트리거 조건을 설정할 때는 트리거를 실행한 동작에 적합한 inserted 및 deleted 테이블을 사용합니다.When you set trigger conditions, use the inserted and deleted tables appropriately for the action that fired the trigger. INSERT를 테스트할 때 deleted 테이블을 참조하거나 DELETE를 테스트할 때 inserted 테이블을 참조해도 오류가 발생하지는 않지만 이러한 경우 트리거 테스트 테이블에는 아무 행도 들어 있지 않습니다.Although referencing the deleted table when testing an INSERT or the inserted table when testing a DELETE does not cause any errors, these trigger test tables do not contain any rows in these cases.

참고

트리거 동작이 데이터 수정의 영향을 받는 행의 수에 따라 달라지는 경우 여러 행 데이터 수정(SELECT 문을 기반으로 하는 INSERT, DELETE 또는 UPDATE)에 @@ROWCOUNT 검사 같은 테스트를 사용하고 적합한 작업을 수행합니다.If trigger actions depend on the number of rows a data modification effects, use tests (such as an examination of @@ROWCOUNT) for multirow data modifications (an INSERT, DELETE, or UPDATE based on a SELECT statement), and take appropriate actions.

SQL Server 2017SQL Server 2017 에서는 inserted 및 deleted 테이블에서 AFTER 트리거에 대한 text, ntext또는 image 열 참조를 허용하지 않습니다. does not allow for text, ntext, or image column references in the inserted and deleted tables for AFTER triggers. 하지만 이러한 데이터 형식은 단지 이전 버전과의 호환성을 위해 포함된 것입니다.However, these data types are included for backward compatibility purposes only. 큰 데이터를 저장하는 경우 varchar(max), nvarchar(max)varbinary(max) 데이터 형식을 사용하는 것이 좋습니다.The preferred storage for large data is to use the varchar(max), nvarchar(max), and varbinary(max) data types. AFTER 및 INSTEAD OF 트리거는 모두 inserted 및 deleted 테이블에서 varchar(max), nvarchar(max)varbinary(max) 데이터를 지원합니다.Both AFTER and INSTEAD OF triggers support varchar(max), nvarchar(max), and varbinary(max) data in the inserted and deleted tables. 자세한 내용은 CREATE TRIGGER(Transact-SQL)를 참조하세요.For more information, see CREATE TRIGGER (Transact-SQL).

비즈니스 규칙을 적용하기 위해 트리거의 inserted 테이블을 사용하는 예An Example of Using the inserted Table in a Trigger to Enforce Business Rules

CHECK 제약 조건은 열 수준 또는 테이블 수준 제약 조건이 정의된 열만 참조할 수 있으므로 모든 상호 테이블 제약 조건(이 경우 업무 규칙)을 트리거로 정의해야 합니다.Because CHECK constraints can reference only the columns on which the column-level or table-level constraint is defined, any cross-table constraints (in this case, business rules) must be defined as triggers.

다음 예에서는 DML 트리거를 만듭니다.The following example creates a DML trigger. 이 트리거는 PurchaseOrderHeader 테이블에 새 구매 주문을 삽입하려고 할 때 공급업체의 신용 등급이 양호한지 확인합니다.This trigger checks to make sure the credit rating for the vendor is good when an attempt is made to insert a new purchase order into the PurchaseOrderHeader table. 방금 삽입된 구매 주문에 해당하는 공급업체의 신용 등급을 가져오려면 Vendor 테이블이 참조되어 inserted 테이블과 조인되어야 합니다.To obtain the credit rating of the vendor corresponding to the purchase order that was just inserted, the Vendor table must be referenced and joined with the inserted table. 신용 등급이 너무 낮으면 메시지가 표시되고 삽입이 실행되지 않습니다.If the credit rating is too low, a message is displayed and the insertion does not execute. 이 예에서는 다중 행 데이터 수정을 허용하지 않습니다.Note that this example does not allow for multirow data modifications. 자세한 내용은 Create DML Triggers to Handle Multiple Rows of Data를 참조하세요.For more information, see Create DML Triggers to Handle Multiple Rows of Data.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('Purchasing.LowCredit','TR') IS NOT NULL
   DROP TRIGGER Purchasing.LowCredit;
GO
-- This trigger prevents a row from being inserted in the Purchasing.PurchaseOrderHeader table
-- when the credit rating of the specified vendor is set to 5 (below average).

CREATE TRIGGER Purchasing.LowCredit ON Purchasing.PurchaseOrderHeader
AFTER INSERT
AS
IF EXISTS (SELECT *
           FROM Purchasing.PurchaseOrderHeader p 
           JOIN inserted AS i 
           ON p.PurchaseOrderID = i.PurchaseOrderID 
           JOIN Purchasing.Vendor AS v 
           ON v.BusinessEntityID = p.VendorID
           WHERE v.CreditRating = 5
          )
BEGIN
RAISERROR ('A vendor''s credit rating is too low to accept new
purchase orders.', 16, 1);
ROLLBACK TRANSACTION;
RETURN 
END;
GO

-- This statement attempts to insert a row into the PurchaseOrderHeader table
-- for a vendor that has a below average credit rating.
-- The AFTER INSERT trigger is fired and the INSERT transaction is rolled back.

INSERT INTO Purchasing.PurchaseOrderHeader (RevisionNumber, Status, EmployeeID,
VendorID, ShipMethodID, OrderDate, ShipDate, SubTotal, TaxAmt, Freight)
VALUES (
2
,3
,261	
,1652	
,4	
,GETDATE()
,GETDATE()
,44594.55	
,3567.564	
,1114.8638 );
GO

INSTEAD OF 트리거에서 inserted 및 deleted 테이블 사용Using the inserted and deleted Tables in INSTEAD OF Triggers

테이블에 정의된 INSTEAD OF 트리거로 전달되는 inserted 및 deleted 테이블은 AFTER 트리거로 전달되는inserted 및 deleted 테이블과 같은 규칙을 따릅니다.The inserted and deleted tables passed to INSTEAD OF triggers defined on tables follow the same rules as the inserted and deleted tables passed to AFTER triggers. inserted 및 deleted 테이블의 형식은 INSTEAD OF 트리거가 정의된 테이블의 형식과 같습니다.The format of the inserted and deleted tables is the same as the format of the table on which the INSTEAD OF trigger is defined. inserted 및 deleted 테이블의 각 열은 기본 테이블의 열로 직접 매핑됩니다.Each column in the inserted and deleted tables maps directly to a column in the base table.

INSTEAD OF 트리거가 있는 테이블을 참조하는 INSERT 또는 UPDATE 문이 열 값을 제공해야 하는 경우와 관련된 다음 규칙은 테이블에 INSTEAD OF 트리거가 없는 경우와 동일합니다.The following rules regarding when an INSERT or UPDATE statement referencing a table with an INSTEAD OF trigger must supply values for columns are the same as if the table did not have an INSTEAD OF trigger:

  • 계산 열이나 timestamp 데이터 형식의 열에는 값을 지정할 수 없습니다.Values cannot be specified for computed columns or columns with a timestamp data type.

  • 해당 테이블에 대해 IDENTITY_INSERT가 ON으로 설정되어 있지 않으면 IDENTITY 속성이 있는 열에 값을 지정할 수 없습니다.Values cannot be specified for columns with an IDENTITY property, unless IDENTITY_INSERT is ON for that table. IDENTITY_INSERT가 ON이면 INSERT 문이 값을 제공해야 합니다.When IDENTITY_INSERT is ON, INSERT statements must supply a value.

  • INSERT 문은 DEFAULT 제약 조건이 없는 모든 NOT NULL 열에 값을 제공해야 합니다.INSERT statements must supply values for all NOT NULL columns that do not have DEFAULT constraints.

  • 계산 열, ID 열 또는 timestamp 열을 제외한 모든 열에서 Null을 허용하는 열 또는 DEFAULT 정의가 있는 NOT NULL 열의 경우 값이 선택적입니다.For any columns except computed, identity, or timestamp columns, values are optional for any column that allows nulls, or any NOT NULL column that has a DEFAULT definition.

    INSERT, UPDATE 또는 DELETE 문에서 INSTEAD OF 트리거가 있는 뷰를 참조할 때 데이터베이스 엔진Database Engine 은 테이블에 대해 직접 동작을 수행하는 대신 트리거를 호출합니다.When an INSERT, UPDATE, or DELETE statement references a view that has an INSTEAD OF trigger, the 데이터베이스 엔진Database Engine calls the trigger instead of taking any direct action against any table. 뷰에 대해 작성된 inserted 및 deleted 테이블의 정보 형식이 기본 테이블에 있는 데이터 형식과 다른 경우에도 트리거는 inserted 및 deleted 테이블에 있는 정보를 사용하여 기본 테이블에서 요청된 동작을 구현하는 데 필요한 문을 작성해야 합니다.The trigger must use the information presented in the inserted and deleted tables to build any statements required to implement the requested action in the base tables, even when the format of the information in the inserted and deleted tables built for the view is different from the format of the data in the base tables.

    뷰에 정의된 INSTEAD OF 트리거로 전달되는 inserted 및 deleted 테이블의 형식은 뷰에 대해 정의된 SELECT 문의 선택 목록과 일치합니다.The format of the inserted and deleted tables passed to an INSTEAD OF trigger defined on a view matches the select list of the SELECT statement defined for the view. 예를 들어For example:

USE AdventureWorks2012;  
GO  
CREATE VIEW dbo.EmployeeNames (BusinessEntityID, LName, FName)  
AS  
SELECT e.BusinessEntityID, p.LastName, p.FirstName  
FROM HumanResources.Employee AS e   
JOIN Person.Person AS p  
ON e.BusinessEntityID = p.BusinessEntityID;  

이 뷰의 결과 집합에는 int 열 하나와 nvarchar 열 두 개가 있습니다.The result set for this view has three columns: an int column and two nvarchar columns. 뷰에 정의된 INSTEAD OF 트리거로 전달되는 inserted 및 deleted 테이블에는 또한 라는 int BusinessEntityID열, 이라는 nvarchar LName열 및 이라는 nvarchar FName열이 있습니다.The inserted and deleted tables passed to an INSTEAD OF trigger defined on the view also have an int column named BusinessEntityID, an nvarchar column named LName, and an nvarchar column named FName.

뷰의 선택 목록에는 단일 기본 테이블 열에 직접 매핑되지 않는 식이 포함될 수도 있습니다.The select list of a view can also contain expressions that do not directly map to a single base-table column. 상수 또는 함수 호출과 같은 일부 뷰 식은 열을 참조하지 않으므로 무시될 수 있습니다.Some view expressions, such as a constant or function invocation, may not reference any columns and can be ignored. 복합 식은 여러 개의 열을 참조할 수 있지만 inserted 및 deleted 테이블에는 삽입된 각 행에 대해 하나의 값만 있습니다.Complex expressions can reference multiple columns, yet the inserted and deleted tables have only one value for each inserted row. 뷰의 단순 식에서 복합 식이 있는 계산 열을 참조하는 경우에도 마찬가지입니다.The same issues apply to simple expressions in a view if they reference a computed column that has a complex expression. 뷰의 INSTEAD OF 트리거는 이러한 유형의 식을 처리해야 합니다.An INSTEAD OF trigger on the view must handle these types of expressions.