2012-06-14 5 views
1

테이블 A의 모든 기존 행을 테이블 B로 이동해야합니다. 또한 테이블 A에서 이동 된 행만 선택해야합니다 (테이블 B는 테이블 B가 아니기 때문에 테이블 B는 아카이브이므로 많은 행이 포함됩니다). 선택은 많은 시간)테이블 A에서 B로 행을 이동하고 A에서 이동 된 행만 선택하는 방법?

을 복용 나는

레코드가 내가 확인해야합니다 표 A에 연속적으로 삽입되어 있습니다 마이크로 소프트 SQL 서버 2008과 닷넷 (의 System.Data.SQLClient)를 사용하고 있습니다 이동 된 레코드 만 선택되고 삭제되기 전에 표 A에서 선택됩니다.

가장 효율적인 방법은 무엇입니까? 난 당신이 같은 것을 할 싶습니다 이해하는 것과

+1

레코드를 테이블 A에서 B로 이동하면 레코드 전송 후 테이블 A에서 동일한 레코드를 읽는 방법. 복사 작업이 아닌 이동이라고 생각합니다. –

+0

분명히 이동하기 전에 선택해야합니다. – Harindaka

+0

원본 테이블에 타임 스탬프/자동 번호 필드를 만들 수 있습니다.이 필드를 기반으로 이동할 레코드를 식별 할 수 있습니다. –

답변

0

내가가 마침내 수 있었다 SQL Server의 OUTPUT 절을 사용하여이 문제를 해결하십시오. 아래를보십시오. IMO 나는이 방법이 불필요한 잠금을 유지할 이유가 없음을 알았다.

declare @TempTable TABLE(Col1 bigint, Col2 varchar(50)) 

delete from TableA 
output Deleted.Col1, Deleted.Col2 INTO @TempTable 

insert into TableB (Col1, Col2) 
select Col1, Col2 from @TempTable 

select Col1, Col2 from @TempTable 

도움 주셔서 감사합니다.

+0

이것은 본질적으로 나의 대답과 같은 일을한다. 그렇지 않습니까? 광산이 먼저 선택하고 여분의 @ 테이블은 포함되지 않습니다. –

+0

네가 네가 테이블을 잠그는 것을 제외하고는 거의 그렇다. – Harindaka

+0

차단 작업이 아니길 원하십니까? –

1

:

SELECT [] 
INTO archivetable 
FROM activetable 

SELECT [] 
FROM activetable 
WHERE id in (SELECT id from archivetable) 

DELETE 
FROM activetable 
WHERE id in (SELECT id from archivetable) 

이 선택하고 다소 안전한 방법으로 삭제, 복사합니다.

+0

수십억 개의 레코드가있을 수 있으므로 archivetable을 검사하는 것은 매우 느립니다. –

+1

두 번째 쿼리에 관해서는 필자는 선택 및 삭제 쿼리에 아카이브 테이블을 포함시키고 싶지 않고 상당히 느리게 수행 할 것입니다. 실 거예요? 다른 방법이라도? – Harindaka

+0

네,하지만 이것은 기본 키를 사용하는 것을 의미합니다 ... –

3

당신은 같은 것을 할 수 없습니다 :

물론
BEGIN TRANSACTION; 

SELECT * FROM source WITH (HOLDLOCK) 
WHERE ... 

DELETE source 
OUTPUT deleted.* INTO destination 
WHERE ...; 

COMMIT TRANSACTION; 

당신이 * SELECT 사용하지 것이다하지만 난 그래서 당신의 테이블 모른다 ...

+0

트랜잭션이 완료 될 때까지 아무도 소스 테이블의 레코드를 업데이트 할 수 없습니다. 새로운 레코드 삽입을 의미하지 않습니다. –

+0

@Romil OP가 이산 열 집합에 대해이 작업을 수행하기를 원하는 경우 필수적입니다. 그렇지 않으면 소스 테이블이 중간 트랜잭션을 변경할 수 있습니다. – JNK

+0

트랜잭션없이 이것을 실행하려면 삭제 된 쿼리를 테이블 변수에 출력 한 다음이를 선택하여 아카이브에 삽입하십시오. –

관련 문제