일부 영구 데이터가있는 테이블이 있습니다. 이제 쿼리 할 때 결과에 필요한 값을 계산하고 누락 된 행을 영구 테이블에 삽입해야하는 꽤 복잡한 CTE가 있습니다. 결국 나는 CTE에 의해 식별 된 모든 행으로 구성된 결과를 선택하려고하지만 테이블에 이미있는 경우 테이블의 데이터로 선택하려고합니다. 행 삽입 여부에 관계없이 정보가 필요합니다. 나는 WHEN MATCHED THEN UPDATE
부분이 마음에 들지SQL MERGE 문에서 UPDATE-no-op
-- Set-up of test data, this would be the persisted table
DECLARE @target TABLE (id int NOT NULL PRIMARY KEY) ;
INSERT INTO @target (id) SELECT v.id FROM (VALUES (1), (2)) v(id);
-- START OF THE CODE IN QUESTION
-- The result table variable (will be several columns in the end)
DECLARE @result TABLE (id int NOT NULL, new bit NOT NULL) ;
WITH Source AS (
-- Imagine a fairly expensive, recursive CTE here
SELECT * FROM (VALUES (1), (3)) AS Source (id)
)
MERGE INTO @target AS Target
USING Source
ON Target.id = Source.id
-- Perform a no-op on the match to get the output record
WHEN MATCHED THEN
UPDATE SET Target.id=Target.id
WHEN NOT MATCHED BY TARGET THEN
INSERT (id) VALUES (SOURCE.id)
-- select the data to be returned - will be more columns
OUTPUT source.id, CASE WHEN $action='INSERT' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END
INTO @result ;
-- Select the result
SELECT * FROM @result;
차라리 중복 업데이 트를 떠날 것,이는 다음과 같이 작동 단순화
(당신이 그것을 시도하려는 경우 다음 코드는 일반 쿼리로 실행) 멀리하지만 OUTPUT
절에 결과 행이 표시되지 않습니다.
이런 종류의 데이터를 완료하고 반환하는 가장 효율적인 방법입니까?
또는 new=0
이다 행의 INSERT
수행 후 SELECT
와 함께 그 결과를 미리 계산함으로써 인스턴스 MERGE
없이 더 효율적인 솔루션을있을 것인가? 쿼리 계획을 해석하는 데 어려움이 있습니다. 기본적으로 성능이 현저하게 떨어지는 "클러스터 된 인덱스 병합"이 SELECT
에 이어 INSERT
변형에 이어집니다. 그리고 SQL Server (2008 R2 with CU1)가 실제로 똑똑해서 UPDATE
이 no-op (예 : 쓰기 필요 없음)인지 알 수 있을지 궁금합니다.
나는 with, merge 및 redundant update와 동일한 설정을 가지고 있으며 실제로 업데이트를 수행하지 않지만 여전히 ID를 반환하는 솔루션을 찾고 있습니다. 해결책을 찾으면 그것을 추가하십시오 =) –
RE : 비 업데이트 업데이트 여기 설명 된대로 클러스터링 키의 일부가 아닌 열에서 No-OP 업데이트를 수행하는 것이 좋습니다 (가능한 경우) //sqlblog.com/blogs/paul_white/archive/2010/08/11/the_2D00_impact_2D00_of_2D00_update_2D00_statements_2D00_that_2D00_don_2D00_t_2D00_change_2D00_data.aspx –
@David Mårtensson, 현상금을 추가해 주셔서 감사합니다. :) – Lucero