It sounds like what you want to do is to create a new boundary for your existing partitioning implementation, and this can be one through ALTER PARTITION FUNCTION ... SPLIT RANGE ...
.
You will also need to run prior to this an ALTER PARTITION SCHEME ... NEXT USED ...
to indicate the next filegroup that will hold the new partition (there are a few caveats to this, as quoted below). Here is a quote from BOL regarding this operation:
A filegroup must exist online and be marked by the partition scheme that uses the partition function as NEXT USED to hold the new partition. Filegroups are allocated to partitions in a CREATE PARTITION SCHEME statement. If a CREATE PARTITION SCHEME statement allocates more filegroups than necessary (fewer partitions are created in the CREATE PARTITION FUNCTION statement than filegroups to hold them), then there are unassigned filegroups, and one of them is marked NEXT USED by the partition scheme. This filegroup will hold the new partition. If there are no filegroups marked NEXT USED by the partition scheme, you must use ALTER PARTITION SCHEME to either add a filegroup, or designate an existing one, to hold the new partition.
When you are working with partition switching, SQL Server will need to verify that the source table/partition boundaries can fit in the destination table/partition boundaries. In other words, you're trying to switch data from dbo.temp_table
to dbo.play_table
's partition 2. Think of it like this, the data for the c1
in dbo.temp_table
is constrained only by the data type (int
), so you can have values ranging from -2,147,483,648 to 2,147,483,647. But conversely, you're destination (dbo.play_table
partition 2) has a range from 4 to 2,147,483,647.
Your data does not violate this, but it is the metadata that can't allow this. You could just as easily insert the value -10 into dbo.temp_table
. The partition switching would fail the same way and make more sense, as -10 does not fit in dbo.play_table
's 2nd partition boundaries.
If you wanted to make this code work, you'd need to explicitly tell SQL Server that dbo.temp_table
will never have any data that won't fit in dbo.play_table
's 2nd partition. You could do this with a check constraint:
/******************************************************************************
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
******************************************************************************/
That above sample addition to your code makes this a working solution. Now SQL Server knows that the data in dbo.temp_table
can fit in partition 2 of dbo.play_table
because of the added check constraint to dbo.temp_table
.
Best Answer
I hate to say this, but there's a bug in Books Online. The Books Online page on partition switching says:
But as you've discovered ANSI_PADDING is also involved - both the incoming & outgoing tables have to have the same setting. There is no way to fix this after the data is loaded.