Reputation: 43
I want to dynamically declare the range of my partition function. I don't want to hard-code the range value,like below:
CREATE PARTITION FUNCTION PartFun(smallint)AS RANGE LEFT FOR VALUES (1,2,3,4,5)
The problem is:The column(ID in IDMASTER table) on which I want to create partition is of smallint datatype.
Declare @IDS NVARCHAR(100)
SELECT @IDS = coalesce(@IDS + ', ', '') + CAST(a.ID AS VARCHAR) FROM
(SELECT DISTINCT TOP 100 ID from IDMASTER ORDER BY ID ) a
--PRINT @IDS --it prints 0,1,2,3,4 like that
CREATE PARTITION FUNCTION PartFun(smallint)
AS RANGE LEFT FOR VALUES (@IDS)
Getting this error:
"Could not implicitly convert range values type specified at ordinal 1 to partition function parameter type."
Any workaround idea? Also,is it that people mostly use hard coded values for partition range?
Upvotes: 2
Views: 15436
Reputation: 957
--Create date partition function with increment by month.
DECLARE @DatePartitionFunction nvarchar(max) =
N'CREATE PARTITION FUNCTION DatePartitionFunction (datetime)
AS RANGE RIGHT FOR VALUES (';
DECLARE @i datetime = '20190101';
WHILE @i < '20221231'
BEGIN
SET @DatePartitionFunction += '''' + CONVERT(CHAR(8),@i,112) + '''' + N', ';
SET @i = DATEADD(MM, 1, CONVERT(CHAR(8),@i,112));
END
SET @DatePartitionFunction += '''' + CONVERT(CHAR(8),@i,112)+ '''' + N');';
EXEC sp_executesql @DatePartitionFunction
--print @DatePartitionFunction;
GO
Upvotes: 1
Reputation: 39
Well what you can do is this:
Use QuoteName(exp,'''')
While creating your string of values (in this case ids) and the rest remains the same. Then execute it normally and it works great.
Upvotes: 0
Reputation: 43
Thanks, got idea. This is how I have solved it:
DECLARE @sqlcmd nvarchar(400),@ids nvarchar(100);
SET @sqlcmd = N'CREATE PARTITION FUNCTION PartFun(smallint) AS RANGE LEFT FOR VALUES (' + @ids + N')' ;
--PRINT @sqlcmd
EXEC SP_EXECUTESQL @sqlcmd
So the solution is:Dynamic SQL and making everything as NVARCHAR!
Upvotes: 0
Reputation: 10843
May not be an exact solution to what you are looking for. Here is the scenario I am faced with:
We have a DB that has multiple tables partitioned on a column named 'PriceListDate', but strangely, the data type is Varchar(8). We are in the middle of redesigning the application and the DB, so decided to change the data type to 'Date'. Here is how we are doing this dynamically:
IF NOT EXISTS (SELECT NULL FROM sys.partition_functions WHERE name = N'PriceListDateFunction')
BEGIN;
DECLARE @CreatePartitionFunctionScript NVARCHAR(MAX);
SET @CreatePartitionFunctionScript = 'CREATE PARTITION FUNCTION [PriceListDateFunction] (Date) AS RANGE LEFT FOR VALUES (' +
STUFF((SELECT ','+'N'+''''+CAST(prv.value as varchar(8))+''''
FROM sys.partition_range_values prv
INNER JOIN sys.partition_functions pf
ON pf.function_id = prv.function_id
WHERE pf.name = 'PriceListFunction'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'') --Get list of existing partitons from existing partition function
+ ')';
-- Create Partition Function
EXECUTE sp_executesql @CreatePartitionFunctionScript;
END;
Hope this gives you some ideas.
Raj
Upvotes: 2