ALTER TABLE… 일반 테이블에서 파티션 된 테이블로의 전환에 실패 NAME =

아래 코드는 다음을 수행합니다.

  1. C : \ TEMP에 데이터베이스 play_partition을 만듭니다.
  2. 두 개의 동일한 파티션 된 테이블 play_table 및 archive_play_table을 작성합니다.
  3. play_table 파티션 1을 archive_play_table 파티션 1로 전환
  4. play_table 파티션 2와 동일한 파일 그룹에서 play_table과 동일한 구조로 파티션되지 않은 새로운 테이블 temp_table을 만듭니다.
  5. play_table_partition 2를 temp_table로 전환
  6. temp_table을 play_table 파티션 2로 다시 전환하려고 시도하고 실패합니다.

    메시지 4982, 수준 16, 상태 1, 줄 64 ALTER TABLE SWITCH 문이 실패했습니다. 소스 테이블 ‘play_partition.dbo.temp_table’의 제한 조건 점검은 대상 테이블 ‘play_partition.dbo.play_table’에서 파티션 2에 의해 정의 된 범위에서 허용되지 않는 값을 허용합니다.

왜 실패합니까?

SQL Server 2014 (Enterprise Edition Trial)를 사용하고 있습니다.

문안 인사,

콜린 데일리

http://www.colindaley.com/translator

/* Playing with partitioned tables */

USE master;
GO

DROP DATABASE play_partition;
GO

CREATE DATABASE play_partition
    ON PRIMARY(
        NAME = play_partition
        , FILENAME = 'C:\TEMP\play_partition.mdf')
    ,FILEGROUP play_fg1(
        NAME = play_fg1
        ,FILENAME = 'C:\TEMP\play_fg1f1.ndf')
    ,FILEGROUP play_fg2(
        NAME = play_fg2f1
        ,FILENAME = 'C:\TEMP\play_fg2f1.ndf');
GO

USE play_partition;


CREATE PARTITION FUNCTION play_range(INT)
    AS RANGE LEFT FOR VALUES(3);

-- Partition scheme
CREATE PARTITION SCHEME play_scheme
    AS PARTITION play_range TO (play_fg1, play_fg2);

-- Partitioned tables
CREATE TABLE dbo.play_table(
    c1 INT NOT NULL CONSTRAINT PK_play_table_c1 PRIMARY KEY CLUSTERED
)
    ON play_scheme(c1);

CREATE TABLE dbo.archive_play_table(
c1 INT NOT NULL CONSTRAINT PK_archive_play_table_c1 PRIMARY KEY CLUSTERED
)
    ON play_scheme(c1);

-- partition 1 = {1, 2, 3}, partiion 2 = {4, 5, 6}
INSERT INTO dbo.play_table(c1) VALUES (1), (2),  (3), (4), (5), (6);

-- move partition 1 from play_table to archive play_table
ALTER TABLE dbo.play_table
    SWITCH PARTITION 1 to dbo.archive_play_table PARTITION 1;

-- create empty table with same structure as dbo.play_table
SELECT * INTO dbo.temp_table FROM dbo.play_table WHERE 1 = 0;

-- move temp_table to filegroup play_fg2
ALTER TABLE dbo.temp_table
    ADD CONSTRAINT PK_temp_table_c1 PRIMARY KEY CLUSTERED(c1) ON play_fg2;

-- move contents of play_table to temp_table, which is not partitioned
-- but is in the same filegroup
ALTER TABLE dbo.play_table
    SWITCH PARTITION 2 TO temp_table;
PRINT 'Switched from partitioned table to non-partitioned table';

-- move data back to partitioned play_table from unpartitioned temp_table
-- FAIL
ALTER TABLE dbo.temp_table
    SWITCH TO play_table partition 2;
PRINT 'Switched from non-partitioned table to partitioned table';


SELECT 'archive_play_table' as table_name, t1.c1
    FROM dbo.archive_play_table AS t1
    UNION ALL
    SELECT 'temp_table' AS table_name, t1.c1
        FROM dbo.temp_table as t1
    ORDER BY 1, 2;



답변

파티션 전환 작업을 수행 할 때 SQL Server는 원본 테이블 / 파티션 경계가 대상 테이블 / 파티션 경계에 맞는지 확인해야합니다. 즉, 전환 데이터를하려는 dbo.temp_tabledbo.play_table의에 대한 데이터를 이런 식으로 생각합니다 파티션의 c1에서이 dbo.temp_table데이터 유형 (의해서만 제한된다 int당신이 -2,147,483,648에서 2,147,483,647까지의 값을 가질 수 있도록) . 그러나 반대로 목적지 ( dbo.play_table파티션 2)의 범위는 4에서 2,147,483,647입니다.

귀하의 데이터는이를 위반하지 않지만이를 허용 할 수없는 메타 데이터입니다. 값 -10을에 쉽게 삽입 할 수 있습니다 dbo.temp_table. -10이 dbo.play_table두 번째 파티션 경계에 맞지 않기 때문에 파티션 전환도 같은 방식으로 실패하고 더 의미가 있습니다.

이 코드를 작동 시키려면 SQL Server에 명시 적으로 2 번째 파티션에 dbo.temp_table맞지 않는 데이터를 가지지 말아야 dbo.play_table합니다. 점검 제한 조건으로이를 수행 할 수 있습니다.

/******************************************************************************
    your code omitted for brevity
******************************************************************************/

-- move contents of play_table to temp_table, which is not partitioned
-- but is in the same filegroup
ALTER TABLE dbo.play_table
    SWITCH PARTITION 2 TO temp_table;
PRINT 'Switched from partitioned table to non-partitioned table';

/******************************************************************************
    added check constraint so that data can fit in the destination partition
******************************************************************************/
alter table dbo.temp_table
add constraint CK_TempTable_C1 check (c1 >= 4);
go
/******************************************************************************
    end of added code
******************************************************************************/

-- move data back to partitioned play_table from unpartitioned temp_table
-- this will no longer FAIL
ALTER TABLE dbo.temp_table
    SWITCH TO play_table partition 2;
PRINT 'Switched from non-partitioned table to partitioned table';

/******************************************************************************
    your code omitted for brevity
******************************************************************************/

위의 코드를 샘플에 추가하면 이것이 효과적인 솔루션입니다. 이제 SQL Server는에 대한 검사 제한 조건으로 인해 dbo.temp_table파티션 2에 데이터 가 들어갈 수 있음을 알고 있습니다 .dbo.play_tabledbo.temp_table


답변