If you print out your sql and examine it then you will find all sorts of errors - and not where you indicated!
You have already generated the comma separated list of columns to retrieve so there is no need to use
SELECT ' + STUFF(@columns, 1, 2, '')
That is the bit that is removing the "I" from the "ISNULL" that is in
@Scolumns
You're doing something similar with
+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
I'm assuming that #Temp contains a list of month names but it's still not clear what you are trying to do.
Something
like this is closer to what you need
DECLARE @Scolumns NVARCHAR(MAX) -- this will include the ISNULL
DECLARE @columns NVARCHAR(MAX) -- this will just be the list of columns
SELECT @scolumns = ISNULL(@Scolumns + ',','')+ 'ISNULL(' + QUOTENAME(Name) + ', 0) AS '+ QUOTENAME(Name)
FROM (
SELECT Name FROM #Temp
) AS x;
SELECT @columns = ISNULL(@columns + ',','')+ QUOTENAME(Name)
FROM (
SELECT Name FROM #Temp
) AS x;
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT ' + @Scolumns + '
FROM
(
SELECT SaleQuantity,CONVERT(VARCHAR,YEAR(MonthOf))+''_''+DATENAME(MM,MonthOF) AS MonthNames FROM TEST (NOLOCK)
) AS j
PIVOT
(
SUM(SaleQuantity) FOR MonthNames IN (' + @columns + ')
) AS p;';
PRINT @sql;
Note that you can't include the ISNULL in the list of columns for the PIVOT so you have to have two variables.
I suggest that you write your query for only a few rows (hard-code the column names) and make sure your query works. Then work on generating the list of columns dynamically - print these out and paste them into your manual, hard-coded query. Confirm it works
Then put it all together into the dynamic sql you need