SQL Invalid Column error on Dynamic Query - sql-server

I have the following query:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName = ISNULL(#ColumnName + ',','') + QUOTENAME(MaxDate)
FROM (SELECT DISTINCT MaxDate FROM CustPeriodTable) AS MaxDates
SET #DynamicPivotQuery =
N'SELECT ' + #ColumnName + ' AS Test, min(rn)
FROM CustPeriodTable '
EXEC sp_executesql #DynamicPivotQuery
I'm getting an invalid column name error for every entry in #ColumnName. I'm in the process of setting up a more complicated query that will involve a pivot but I'm trying to get this chunk working first. Can anyone point out where this problem might be coming from?

For these types of issues you need to look at what the dynamic query is. Instead of executing it just select it.
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName = ISNULL(#ColumnName + ',','') + QUOTENAME(MaxDate)
FROM (SELECT DISTINCT MaxDate FROM CustPeriodTable) AS MaxDates
SET #DynamicPivotQuery =
N'SELECT ' + #ColumnName + ' AS Test, min(rn)
FROM CustPeriodTable '
SELECT #DynamicPivotQuery
-- EXEC sp_executesql #DynamicPivotQuery
From here you should be able to determine what the issue is.

Related

Unpivot all other columns

Im new to Stack overflow and SQL and I'm trying to replicate a function in Microsoft Power Query to use in SQL instead.
I know how to Unpivot and keep 1 Column in SQL and then had to reference all the other columns by name to make the unpivot.
Now I need to Keep 3 ID columns and Unpivot the rest of the columns
(This table has 355 columns right now and will change)
Can anyone help me with this?
This is the furthest I got (Thanks to RAV DBLearning on Youtube), but I cant seem to find a way to Convert the columns types to 1 type.
DECLARE
#SQLSTRING NVARCHAR(MAX),
#COLUMNLIST NVARCHAR(1000) = ''
SELECT
#COLUMNLIST = #COLUMNLIST + QUOTENAME(NAME) + ','
FROM
sys.columns
WHERE
OBJECT_ID = OBJECT_ID('xp.XPROPERTYVALUES') AND
--COLUMN_ID NOT IN(1,2,3)
COLUMN_ID IN(452,453,454)
SELECT
#COLUMNLIST = LEFT(#COLUMNLIST,LEN(#COLUMNLIST)-1)
SET
#SQLSTRING =
'
SELECT
upv.id,
upv.item_id,
upv.itemtype_id,
upv.X_Category,
upv.X_Values
FROM
xp.XPROPERTYVALUES
UNPIVOT
(
X_Values FOR X_Category
IN
(' + #COLUMNLIST + ')
) AS upv
'
PRINT
(#SQLSTRING)
EXECUTE
sp_executesql #SQLSTRING
It just needs a source query.
And you can re-use the calculated column list for that.
DECLARE #SQLSTRING NVARCHAR(MAX),
#COLUMNLIST NVARCHAR(MAX);
DECLARE #TABLENAME VARCHAR(30) = 'xp.XPROPERTYVALUES';
SELECT #COLUMNLIST = CONCAT(#COLUMNLIST + ', ', QUOTENAME(NAME))
FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID(#TABLENAME)
AND LOWER(NAME) NOT LIKE '%id';
SET #SQLSTRING = N'SELECT upv.id
, upv.item_id, upv.itemtype_id
, upv.X_Category, upv.X_Values
FROM
(
SELECT id, item_id, itemtype_id,
'+ #COLUMNLIST + N'
FROM '+ #TABLENAME +N'
) src
UNPIVOT
(
X_Values FOR X_Category IN (' + #COLUMNLIST + N')
) upv';
-- SELECT #SQLSTRING;
EXECUTE sp_executesql #SQLSTRING;
db<>fiddle here

Dynamic pivot with tweaks

I'm trying to solve experiment with some SQL pivoting. I have created a pivot by naming the columns, I am now trying to do it dynamically. From a few searches I have come up with the following code
USE [LMS]
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(Learning_Path_Title)
FROM (SELECT DISTINCT [Learning_Path_Title] FROM [dbo].[copy from]) AS Courses
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT Distinct [Userd], ' + #ColumnName + '
FROM [dbo].[copy from]
PIVOT(MAX([Learning_Path_Complete])
FOR [Learning_Path_Title] IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
My data is structured in the following way
I want the table to be displayed as below

Stored Procedure: Passing a parameter when using dynamic SQL for pivoting data

As the title suggests, I'm trying use dynamic SQL to get column names for a pivoted table - however, I also want to be able to pass a parameter to a variable called #assessments, but I just can't seem to get it to work. Below is the code I'm using, would appreciate if anyone could take a look and let me know where I'm going wrong. Thank you
create PROCEDURE [dbo].[spTestExamResults]
AS
BEGIN
DECLARE #SQL as NVARCHAR(MAX)
DECLARE #ColumnName as NVARCHAR(MAX)
DECLARE #assessment as NVARCHAR(50)
SET NOCOUNT ON;
--Get distinct values from pivot source
SELECT #ColumnName = ISNULL(#ColumnName + ',','') + QUOTENAME(subjectname)
From (SELECT DISTINCT SubjectName From qryPupilNCTest) as p order by p.Subjectname
SET #SQL =
'select pupil,PupilName, year' + #ColumnName + '
FROM qrypupilnctest
Where assessment in (' + #assessment + ')
PIVOT (MAX(grade) for subjectname in (' +#ColumnName + ')) piv'
EXEC (#SQL)
END
In your case, #assessment is the local variable with out any initialization and handled in the operation. So it always have empty value only and you won't get any result from the stored procedure.
As per your post title, you can alter the stored procedure and pass the #assessment as parameter, so the WHERE assessment IN ( will have some valid data and you will receive some valid result.
ALTER PROCEDURE [dbo].[spTestExamResults]
(
#assessment NVARCHAR(50)
)
AS
BEGIN
DECLARE #SQL AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
-- DECLARE #assessment as NVARCHAR(50) -- Remove the #assessment from the local variable
SET NOCOUNT ON;
--Get distinct values from pivot source
SELECT #ColumnName = ISNULL(#ColumnName + ',','') + QUOTENAME(subjectname)
FROM (SELECT DISTINCT SubjectName FROM qryPupilNCTest) AS p
ORDER BY p.Subjectname
SET #SQL = 'SELECT pupil, PupilName, year' + #ColumnName + '
FROM qrypupilnctest
WHERE assessment IN (' + #assessment + ')
PIVOT (MAX(grade) FOR subjectname IN (' + #ColumnName + ')) piv'
EXEC (#SQL)
END
So the execution call will be:
EXEC [dbo].[spTestExamResults] 'paramvalue1, paramvalue2'

How to make a query with dynamic column in sql server 2012

I have the sample code below. The result is such that it takes as these columns as VARCHAR type.
declare #col1 varchar(80)='[Column1]'
declare #col2 varchar(80)='[Column2]'
SELECT #col1,#col2 FROM MyTable
You have to use dynamic SQL:
DECLARE #col1 VARCHAR(80) = 'Column1';
DECLARE #col2 VARCHAR(80) = 'Column2';
DECLARE #sql NVARCHAR(MAX);
SELECT #sql = 'SELECT ' + QUOTENAME(#col1) + ', ' + QUOTENAME(#col2) + ' FROM MyTable;';
EXEC sp_executesql #sql;
Note that you have to make sure that your column names are real column names. You also need to parameterize your query for added security. If you get any of these wrong, it may create huge security problems.
Try,
declare #query nvarchar(500) = 'select ' + #col1 + ', ' + #col1 + ' FROM MyTable'
exec #query

Dynamic Pivot with column names from dynamic tables

I am working on a project with SSRS and Rockwell Software's RSView32. Basically this software project logs manufacturing data to individual tables as such:
One table (Machine1_TagTable) has Tag names which describe the data as such: TagName, TagIndex. The name provides a human-understandable reference to the information contained in a second table. Example : Part Number, 1
The second table (Machine1_FloatTable) contains raw data with nothing more than a timestamp, TagIndex and value.
Example : 2013-12-10 15:44:11.322, 1, 12345(value)
I have a dynamic pivot which works for ONE table; however, I would like to use a variable parameter passed from SSRS to select both the TagTable and FloatTable.
This works with the Machine1_FloatTable as part of the dynamic statement, but not in the XML path building. I understand this is a scope issue, so I'm looking for creative ways to allow me to pass the table names from SSRS into this stored procedure.
Here's what I have now:
DECLARE #FLOATTABLE NVARCHAR(MAX), #TAGTABLE NVARCHAR(MAX), #startdate NVARCHAR(MAX),
#enddate NVARCHAR(MAX), #cols as NVARCHAR(MAX), #query as NVARCHAR(MAX)
SET #TAGTABLE ='dbo.Machine1_TagTable'
SET #FLOATTABLE = 'dbo.Machine1_FloatTable'
SELECT #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CONVERT(VARCHAR,TagName),'"')
FROM #tagtable
FOR XML PATH('')),1,1,'')
Set #query = 'SELECT DISTINCT DateAndTime, Millitm, ' + #cols + ' FROM ( select
T.DateAndTime, T.Millitm, N.TagName, T.Val from ' + #FLOATTABLE + ' T LEFT JOIN ' +
#TAGTABLE + ' N ON T.TagIndex=N.TagIndex WHERE T.DateAndTime Between '''+ #startdate +
''' AND '''+ #enddate +''') x PIVOT (MAX(Val) for TagName IN (' + #cols + ')) p'
PRINT (#query)
Any help or suggestions would be greatly appreciated. Thanks!
Well, it's possible, if I understand your question. You have to build a dynamic SQL string, and execute that to populate #cols.
declare #string nvarchar(MAX)
set #String = 'SELECT STUFF((SELECT DISTINCT '','' + QUOTENAME(CONVERT(VARCHAR,ActualDate),'
+ '''"'') FROM ' + #TAGTABLE + ' FOR XML PATH ('''')),1,1,'''')'
EXECUTE sp_executeSQL #String, #Cols OUTPUT
print #cols
It's pretty hacky, but I think it should work.

Resources