ALTER TABLE ... SWITCHing from regular table to partitioned table fails

  • The code below does the following:

    1) Creates a database play_partition in C:\TEMP

    2) Creates two identical partitioned tables play_table and archive_play_table

    3) Switches play_table partition 1 to archive_play_table partition 1

    4) Creates a new unpartitioned table temp_table with the same structure as play_table on the same filegroup as play_table partition 2

    5) Switches play_table_partition 2 to temp_table

    6) Tries to switch temp_table back to play_table partition 2 and fails with

    Msg 4982, Level 16, State 1, Line 64

    ALTER TABLE SWITCH statement failed. Check constraints of source table

    'play_partition.dbo.temp_table' allow values that are not allowed by

    range defined by partition 2 on target table

    'play_partition.dbo.play_table'.

    Why does it fail?

    I am using SQL Server 2014 (Enterprise Edition Trial).

    Regards,

    Colin Daley

    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;

  • I need a CHECK constraint (c1 >= 4) on temp_table to ensure that values in c1 will always fit in partition 2. Answered at dba.stackexchange.com by Thomas Stringer.

    Is there a way to mark my question as answered?

Viewing 2 posts - 1 through 1 (of 1 total)

You must be logged in to reply to this topic. Login to reply