1 명령문이 더 이상 시간 초과되지 않도록 트랜잭션 시간 제한을 충분히 큰 값으로 설정하십시오.
2를 사용하여 커서를하며 일을하는이 방법을 시도 행
3에 의해 행 않습니다. 행 식별자 (예를 들어 IDENTITY)를, 최선의 해당 필드에서 PK 또는 INDEX를 가질 필요 :
SET NOCOUNT ON;
CREATE TABLE #A(
row_id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
data INT NOT NULL
);
CREATE TABLE #B(
row_id INT NOT NULL PRIMARY KEY,
data INT NOT NULL
);
-- TRUNCATE TABLE #B; -- no truncate needed since you just want to add rows, not copy the whole table
DECLARE @batch_size INT;
SET @batch_size = 10000;
DECLARE @from_row_id INT;
DECLARE @to_row_id INT;
-- You would use this to establish the first @from_row_id if you wanted to copy the whole table
-- SELECT
-- @from_row_id=ISNULL(MIN(row_id),-1)
-- FROM
-- #A AS a;
SELECT
@from_row_id=ISNULL(MAX(row_id),-1)
FROM
#B AS b;
IF @from_row_id=-1
SELECT
@from_row_id=ISNULL(MIN(row_id),-1)
FROM
#A AS a;
ELSE
SELECT
@from_row_id=ISNULL(MIN(row_id),-1)
FROM
#A AS a
WHERE
row_id>@from_row_id;
WHILE @from_row_id>=0
BEGIN
SELECT
@to_row_id=ISNULL(MAX(row_id),-1)
FROM
(
SELECT TOP(@batch_size)
row_id
FROM
#A AS a
WHERE
row_id>[email protected]_row_id
) AS row_ids
IF @to_row_id=-1
BEGIN
INSERT
#B
SELECT
*
FROM
#A AS a
WHERE
row_id>[email protected]_row_id;
BREAK;
END
ELSE
INSERT
#B
SELECT
*
FROM
#A AS a
WHERE
row_id BETWEEN @from_row_id AND @to_row_id;
SELECT
@from_row_id=ISNULL(MIN(row_id),-1)
FROM
#A AS a
WHERE
row_id>@to_row_id;
END
DROP TABLE #B;
DROP TABLE #A;
루프에서 "update top (5000) ..."을 사용하는 것과 같이 더 작은 배치로 업데이트를 실행할 수 있습니다. – Stanley
작은 배치로 삽입하는 것이 좋습니다. 좋은 생각입니다. 그러나 표 B에서 중복을 방지하기 위해 어떤 레코드가 복사되었는지 추적해야합니다. – kevin