Tell me more ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I would think that this would be a fairly simply question, but I've actually had a difficult time finding an answer for this.

The question: Can you move rows of data within a partitioned table from one partition to another by simply updating the partition column so that it crosses the partition boundary?

For example, if I have a table that has a partition key:

CREATE TABLE SampleTable
(
    SampleID INT PRIMARY KEY,
    SampleResults VARCHAR(100) NOT NULL,
)

With the partition function that maps to the primary key:

CREATE PARTITION FUNCTION MyPartitionFunc (INT) AS
RANGE LEFT FOR VALUES (10000, 20000);

Can I move a row from the first partition to the third partition by changing the SampleID from 1 to (say) 500,000?

Note: I'm tagging this as both sql server 2005 and 2008, since they both support partitioning. Do they handle it differently?

share|improve this question

2 Answers

up vote 11 down vote accepted

I do not have a 2005 server to test with. 2008 however, appears to handle this as expected:

USE [Test]
GO
CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO
--Add one record to each partition
INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;
GO
--Move row between partitions
UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;

You should see one record in each partition before the update, and both records in the first partition afterwards.

share|improve this answer
1  
that's a nicely done piece of answer! – Marian Aug 9 '11 at 21:20
This executes as you describe in SQL Server 2005 as well – Ben Brocka Oct 26 '11 at 21:31

I don't think that answer is correct. When you use the value

 $PARTITION.IDRange1([ID]) AS Partition

you are simply recalculating what the partition should be, not where the record currently is.

You should use:

select * from sys.partitions where object_id = object_id('IDRanges')

In my tests on sql 2005 the value changes but the record stays in the same partition. This will probably mess with stats and the optimizer as it will run in a multi threaded mode expecting a partition to be in a specific range. It will also be completely wrong when it tries to use partition elimination to only query the relevant partition. I think you need to delete and re-insert each record to get them to move.

share|improve this answer
2  
Searching for $partition over here suggests that the accepted answer is correct. How are you confirming that the record stays in the same partition after it has been updated? – Nick Chammas Oct 26 '11 at 21:38
-1 This answer is fundamentally wrong in all respects. – Paul White Apr 30 at 5:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.