It needs to be dynamic SQL. Details in the code below. Don't ignore the SQL Injection prevention.
--===== This could be a parameter passed to a stored procedure.
DECLARE @pTableName VARCHAR(257);
SELECT @pTableName = 'dbo.Combinations '
;
--===== Make sure no SQL Injection came in as a table name.
-- Intentionally return no data that an attacker could use
-- to help figure out an attack.
IF OBJECT_ID(@pTableName) IS NULL
RETURN
;
--===== Local Variables
DECLARE @ColNames VARCHAR(MAX)
,@SQL VARCHAR(MAX) --Added this
;
--===== Create the dynamic SQL using the trick of cascading-variables to simplify.
SELECT @ColNames =
STUFF(
(
SELECT ',' + QUOTENAME(name) --QUOTENAME to safeguard against weird column names
FROM sys.columns
WHERE object_id = OBJECT_ID(@pTableName)
ORDER BY column_id
FOR XML PATH('')
)
,1,1,'')
,@SQL = REPLACE(REPLACE( --Pretested code that's been "tokenized" for simplicity.
'SELECT * FROM <<@pTableName>> GROUP BY CUBE (<<@ColNames>>);'
,'<<@pTableName>>',@pTableName)
,'<<@ColNames>>' ,@ColNames) --Uses content created in this same SELECT above.
;
--===== Display the SQL that would be executed.
-- This could be removed for Production.
PRINT @SQL
;
--===== Execute the dynamic SQL
EXEC (@SQL)
;
--Jeff Moden
Change is inevitable... Change for the better is not.