업데이트되는 현재 행 외부의 데이터를 기반으로 계산 된 열을 가질 수 없습니다. 이 기능을 자동으로 수행하는 최선의 방법은 제품 코드의 다음 값을 찾기 위해 전체 테이블을 쿼리하는 사후 트리거를 만드는 것입니다. 하지만이 작업을하기 위해서는 독점적 인 테이블 잠금을 사용해야하는데, 이것은 동시성을 완전히 파괴 할 것이므로 좋은 생각이 아닙니다.
테이블을 읽을 때마다 ProductCode를 계산해야하기 때문에보기 사용을 권장하지 않습니다. 이것은 거대한 성과 - 살인자가 될 것입니다. 데이터베이스에 값을 저장하지 않고 다시 만지면 제품 코드가 잘못 변경 될 수 있습니다 (실수로 입력 한 제품과 사용하지 않은 제품을 삭제 한 경우처럼).
다음은 내가 대신 권장하는 내용입니다. 새 테이블 만들기 :
dbo.SellerProductCode는
SellerID LastProductCode
-------- ---------------
1 3
2 1
이 테이블은 안정적으로 각각의 판매자에 대한 마지막으로 사용한 제품 코드를 기록합니다. INSERT
에서 Product
테이블로 트리거하면 영향을받는 모든 테이블 SellerID
에 대해이 테이블의 LastProductCode
이 적절히 업데이트되고 Product
테이블의 새로 삽입 된 모든 행이 적절한 값으로 업데이트됩니다. 다음과 같이 보일 수 있습니다.
See this trigger working in a Sql Fiddle
이 트리거가 여러 행이 삽입되는 경우에도 작동
CREATE TRIGGER TR_Product_I ON dbo.Product FOR INSERT
AS
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @LastProductCode TABLE (
SellerID int NOT NULL PRIMARY KEY CLUSTERED,
LastProductCode int NOT NULL
);
WITH ItemCounts AS (
SELECT
I.SellerID,
ItemCount = Count(*)
FROM
Inserted I
GROUP BY
I.SellerID
)
MERGE dbo.SellerProductCode C
USING ItemCounts I
ON C.SellerID = I.SellerID
WHEN NOT MATCHED BY TARGET THEN
INSERT (SellerID, LastProductCode)
VALUES (I.SellerID, I.ItemCount)
WHEN MATCHED THEN
UPDATE SET C.LastProductCode = C.LastProductCode + I.ItemCount
OUTPUT
Inserted.SellerID,
Inserted.LastProductCode
INTO @LastProductCode;
WITH P AS (
SELECT
NewProductCode =
L.LastProductCode + 1
- Row_Number() OVER (PARTITION BY I.SellerID ORDER BY P.ProductID DESC),
P.*
FROM
Inserted I
INNER JOIN dbo.Product P
ON I.ProductID = P.ProductID
INNER JOIN @LastProductCode L
ON P.SellerID = L.SellerID
)
UPDATE P
SET P.ProductCode = Right('00000' + Convert(varchar(6), P.NewProductCode), 6);
참고. SellerProductCode
테이블을 미리로드 할 필요가 없습니다. 새 판매자가 자동으로 추가됩니다. 이것은 거의 문제가없는 동시성을 처리합니다. 동시성 문제가 발생하면 표가 매우 작고 ROWLOCK을 사용할 수 있기 때문에 해로운 영향없이 적절한 잠금 힌트를 추가 할 수 있습니다 (범위 잠금이 필요한 INSERT 제외).
see the Sql Fiddle을 수행하여 기술을 입증 한 코드를 테스트하십시오. 이제 변경된 이유가없고 신뢰할 수있는 제품 코드가 있습니다.
이 유형의 계산을 수행하려면보기를 사용하는 것이 좋습니다. 선택 성능이 가장 중요한 요인이라면 뷰를 인덱싱 할 수도 있습니다 (당신이'persisted '를 사용하고있는 것을 봅니다). –
@TimLehner 샘플을 제공해 주시겠습니까? Computed 컬럼을 사용하는 것이 가능한지 아직도 알고 싶습니다. –