If you are working with large databases you have come to situation when you need to partition the large tables.
To be able to partition a table, you need to create a Partition Function. Creation of Partition Function is quite easy, however if you need to create a larger number of partitions at initial phase, it can be pretty annoying as you have to define all the ranges for each partition. Also it is easy to make a type in the list of boundary values and as a result create a partition function with wrong partition alignment.
To simplify that process I’m presenting here a stored procedure which takes care about that and generates the partition function automatically based on input parameters
sp_tblCreatePartitionFunction
As mentioned above, the sp_tblCreatePartitionFunction
takes care about generation of the partition function based on input parameters.
You can find complete source code in my SQL-Scripts project on GitHub under the TablesManagement\Partitioning folder.
The stored procedure provides support for generation of ranges based on smallint
, int
, bigint
, date
, datetime
and datetime2
data types.
Stored procedure generates a partition function with boundary values between @rangeStart
and @rangeEnd
parameters.
The stored procedure is marked as system stored procedure in the script so it means that it can operate in the context of the current user database.
Parameters
The input parameters define the ranges and the way how the partition function is generated
The available input parameters for the function are @pfName
, @rangeStart
, @rangeEnd
, @boundaryType
, @incrementValue
, @incrementUnit
, @useIntegerDates
, @integerFormatType
and @printScriptOnly
@pfName
Defines the partition function Name. the parameter data type is nvarchar(128)
which corresponds to sysname
.
@rangeStart
Defines the starting range for generation of the partition function. The parameter is sql_variant. You have to pass parameter of supported data type for the range. As mentioned above the supported data types are smallint
, int
, bigint
, date
, datetime
and datetime2
.
To simplify specification of the range, you can pass the parameter as string. If the value passed as string represents a DateTime
it is automatically converted to datetime
data type.
You can also pass a value with a data type specifier. The data type specifier must be first character of the string and the value must follow. The supported data type specifiers are 'D' - date
, 'T' - datetime
, 'B' - bigint
, 'I' - int
and 'S' - smallint
.
Below are some examples of supported strings passed as @rangeStart
:
Sample value | Result |
---|---|
'2016-01-01' |
Converted to datetime 2016-01-01 |
20160101 |
Converted to datetime 2016-01-01 |
D2016-01-01 |
Converted to date 2016-01-01 |
T20160101 |
Converted to datetime 2016-01-01 |
B1010 |
Converted to bigint 100 |
I1010 |
Converted to int 100 |
S1010 |
Converted to smallint 100 |
The @rangeStart
representing a date can be altered during the partition function generation based on the @incrementUnit
parameter. The @rangeStart
is shifted to the beginning of corresponding unit.. See the @incrementUnit
parameter for details.
The @rangeStart
is included in the generated ranges.
@rangeEnd
Represents then end of range which should be generated for the partition function. The supported data types are the same as for the @rangeStart
. See the @rangeStart
for details.
The @rangeEnd
is inclusive in the range, but may not be included in the final generated partition function in dependency on the @incrementValue
and @incrementUnit
parameters. See those parameters for details.
@boundaryType
Specifies the boundary type of the boundary values for the partition function. It can be either LEFT
or RIGHT
. It defines whether the boundary value is included in the left or right partition respective to the boundary value. Default value is RIGHT
.
@incrementValue
Defines increment of the boundary values. This means that the @rangeStart
value is incremented by the @incrementValue
until @rangeEnd
is reached.
@incrementUnit
Specifies the unit of the increment. It is being used only for range values representing date. The allowed units are YEAR
, MONTH
, WEEK
, ISO_WEEK
, DAY
.
In each iteration step the @rangeStart
value is incremented by the @incrementValue
number of @incrementUnit.
Also the @incrementUnit
may have impact on the @rangeStart
value. If the @rangeStart
value does not point to the first day of respective unit, it is being automatically shifted to the beginning of corresponding unit based on the @rangeStart
value.
Samples of @rangeStart
shifting:
@rangeStart | @incrementUnit | @rangeStart shifted to |
---|---|---|
'2016-03-17' |
YEAR |
'2016-01-01' |
'2016-03-17' |
MONTH |
'2016-03-01' |
'2016-03-17' |
WEEK |
'2016-03-14' |
'2016-01-01' |
ISO_WEEK |
'2015-12-28' |
@useIntegerDates
Specifies whether boundary values representing dates in the partition function should be represented as int
date types or corresponding date
, datetime
or datetime2
data type. In case of @useIntegerDates = 0
the boundary value is always first day of corresponding @incrementUnit
.
In case of @useIntegerDates =
1 the boundary value is expressed as integer number and the value representing the range depends on the @integerFormatType
parameter. See the @integerFormatType
for details
It is being used only for date ranges. Default value is 1.
@integerFormatType
Specifies integer format of date range value. When the partition function is being generated and date ranges are being used, the range value is internally always represented by a first day of corresponding rage. if the @useIntegerDate = 1
the final boundary value is generated based on the format type.
Supported format types are:
FormatType | Boundary value formatting |
---|---|
1 |
yyyyMMdd For example 20160101 |
2 |
yyyyxx(x) where xxx(x) correspond to appropriate month, week or day within particular year. For example 2016053 represents a day 53 of year 2016. 201643 represents week or iso_week 43 in year 2016 |
Default value is 2.
@printScriptOnly
Specifies whether only the partition function CREATE script is being printed or the partition function is being automatically crated.
The default value is 1, this means that only script is printed.
Samples
Below are some sample usages of the stored procedure.
Sample 1
sp_tblCreatePartitionFunction @pfName = 'myPf' ,@rangeStart = 1 ,@rangeEnd = 1001 ,@boundaryType = 'RIGHT' ,@incrementvalue = 100
CREATE PARTITION FUNCTION [myPf](int) AS RANGE RIGHT FOR VALUES ( 1 ,101 ,201 ,301 ,401 ,501 ,601 ,701 ,801 ,901 ,1001 )
Sample 2
sp_tblCreatePartitionFunction @pfName = 'myPf' ,@rangeStart = '2016-01-01' ,@rangeEnd = '2020-12-31' ,@boundaryType = 'RIGHT' ,@incrementvalue = 1 ,@incrementUnit = 'YEAR' ,@useIntegerDates = 1 ,@integerFormatType = 2
CREATE PARTITION FUNCTION [myPf](int) AS RANGE RIGHT FOR VALUES ( 2016 ,2017 ,2018 ,2019 ,2020 )
Sample 3
sp_tblCreatePartitionFunction @pfName = 'myPf' ,@rangeStart = '2016-01-01' ,@rangeEnd = '2016-12-31' ,@boundaryType = 'LEFT' ,@incrementvalue = 1 ,@incrementUnit = 'MONTH' ,@useIntegerDates = 1 ,@integerFormatType = 2
CREATE PARTITION FUNCTION [myPf](int) AS RANGE LEFT FOR VALUES ( 20160101 ,20160201 ,20160301 ,20160401 ,20160501 ,20160601 ,20160701 ,20160801 ,20160901 ,20161001 ,20161101 ,20161201 )
Sample 4
sp_tblCreatePartitionFunction @pfName = 'myPf' ,@rangeStart = '2016-01-01' ,@rangeEnd = '2016-12-31' ,@boundaryType = 'LEFT' ,@incrementvalue = 1 ,@incrementUnit = 'MONTH' ,@useIntegerDates = 0
CREATE PARTITION FUNCTION [myPf](datetime) AS RANGE LEFT FOR VALUES ( '20160101' ,'20160201' ,'20160301' ,'20160401' ,'20160501' ,'20160601' ,'20160701' ,'20160801' ,'20160901' ,'20161001' ,'20161101' ,'20161201' )