기본 UPSERT 기능을 구현하려고하지만, 실제로는 기존 행을 업데이트하고 싶지 않은 경우가 있습니다.조건부 Upsert 저장 프로 시저를 구현하는 방법은 무엇입니까?
기본적으로 나는 다른 저장소간에 데이터를 동기화하려고하는데, Upsert 함수는 이동하는 것처럼 보입니다. 따라서 대체로 Sam Saffron's answer to this question을 비롯하여 다른 연구 및 읽기를 기반으로이 저장 프로 시저를 만들었습니다.
(참고 : MERGE 문은 옵션이 아니므로 MS SQL Server 2005를 사용하고 있습니다.)
CREATE PROCEDURE [dbo].[usp_UpsertItem]
-- Add the parameters for the stored procedure here
@pContentID varchar(30) = null,
@pTitle varchar(255) = null,
@pTeaser varchar(255) = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN TRANSACTION
UPDATE dbo.Item WITH (SERIALIZABLE)
SET Title = @pTitle,
Teaser = @pTeaser
WHERE ContentID = @pContentID
IF @@rowcount = 0
INSERT INTO dbo.Item (ContentID, Title, Teaser)
VALUES (@pContentID, @pTitle, @pTeaser)
COMMIT TRANSACTION
END
저는 기본적인 Upsert에 만족하지만 실제 업데이트는 다른 열의 값에 조건부로하고 싶습니다. Upsert 절차에 의해 더 이상의 업데이트가 수행되지 않도록 행을 "잠그는"것으로 생각하십시오. 이미 존재하는 행을 삽입하려고하지만 때문에 업데이트되지 않은 경우
UPDATE dbo.Item WITH (SERIALIZABLE)
SET Title = @pTitle,
Teaser = @pTeaser
WHERE ContentID = @pContentID
AND RowLocked = false
을하지만 후속 삽입합니다 (콘텐츠 ID 필드) 고유 제약 조건 위반으로 실패 : 그래서 같은 UPDATE 문을 변경할 수 있습니다 그것은 "잠겨"있었습니다.
이렇게하면 더 이상 고전적인 Upsert가 없다는 것을 의미합니다. 즉, 업데이트 또는 삽입 여부를 결정할 때마다 행을 선택해야합니다. 나는 그럴 것이라고 확신한다. 그래서 내가 정말로 묻고있는 것은 트랜잭션 분리 레벨을 올바르게하는 것이 도움이되어 프로 시저가 안전하게 실행될 수 있다는 것이다.
RowLocked 란 무엇입니까 (AND RowLocked = false)? 테이블에있는 열입니까? –
@AlexKuznetsov - 예, RowLocked는 테이블 열로 간주됩니다. 실제로 행이 "잠겨"있어야하는지 (즉,이 절차로 업데이트되지 않음) 지시하는 두 개의 열이 있지만 내 질문을보다 명확하게하려고 SQL을 단순화했습니다. 비록 문법이 조금 엉성함을 느낀다. 물론 "AND RowLocked = 0"이어야하고, 비트 열이라고 언급해야한다. – Matt