문제

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

  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로 다시 전환하고 로 실패합니다.

    msg 4982, 레벨 16, 상태 1, 64 줄 ALTER TABLE SWITCH 문이 실패했습니다. 소스 표의 제약 조건을 확인하십시오 'play_partition.dbo.temp_table'허용되지 않는 값 허용 대상 표의 파티션 2가 정의한 범위입니다 'play_partition.dbo.play_table'.

    왜 실패합니까?

    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_table에서 dbo.play_table의 파티션으로 데이터를 전환하려고 시도하고 있습니다. 이와 같이 c1dbo.temp_tableint의 데이터는 데이터 유형 (dbo.play_table)에서만 제한되므로 값이 지정할 수 있습니다. 2,147,483,648 ~ 2,147,483,647. 그러나 반대로 목적지 (dbo.temp_table Partit 2)는 4에서 2,147,483,647까지의 범위를 갖습니다.

데이터는이를 위반하지는 않지만이를 허용 할 수없는 메타 데이터입니다. -10을 쉽게 dbo.play_table에 쉽게 삽입 할 수 있습니다. 파티션 스위칭은 dbo.temp_table의 두 번째 파티션 경계에 맞지 않으므로 파티션 스위치가 동일한 방식으로 실패하고 더 의미가 있습니다.

이 코드를 작동 시키려면 dbo.play_table의 두 번째 파티션에 맞지 않는 데이터가 없을 것으로 알려지는 SQL Server에 명시 적으로 알려야합니다. 확인 제약 조건 으로이 작업을 수행 할 수 있습니다.

/******************************************************************************
    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에 추가 된 체크 제약 조건으로 인해 dbo.play_table의 데이터가 PaneracodiceTag 코드의 데이터가 Partity 2에 맞출 수 있음을 알고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 dba.stackexchange
scroll top