alter procedure [dbo].[ParkingDeatailsReport]
as
begin
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#locid INTEGER
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype)
from VType_tbl
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
set #query = 'SELECT Date, ' + #cols + '
from
(
select v.Vtype, convert(date, dtime) as Date
from Transaction_tbl t
inner join VType_tbl v on t.vtid = v.vtid
where locid = ' + CAST(#locid as varchar(max)) + ') d
pivot
(
count(Vtype)
for Vtype in (' + #cols + ')
) p '
execute(#query)
end
Notice the difference between #cols and #locid in dynamic SQL.
Replace
where locid = #locid
With
where locid = ' + CAST(#locid as varchar(max)) + '
Note: while this is a quick fix please see answer from RBarryYoung for best practice with dynamic SQL.
the error clearly say, your current SP code not accepting any parameters and you trying to pas parameters to SP. if you want to accept parameters in SP, syntax is:
Create Procedure Procedure-name
(
Input parameters ,
Output Parameters (If required)
)
As
Begin
Sql statement used in the stored procedure
End
So in your case SP can be change to :
alter procedure [dbo].[ParkingDeatailsReport]
(
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#locid INTEGER
)
as
begin
..... you code go hear
END
Related
I want to declare a table variable and fill it from the pivot with dynamic column to perform join statement.
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
SELECT #cols =
STUFF((SELECT DISTINCT ',' + QUOTENAME(ColName)
FROM [sbs].[ProposalAmounts]
GROUP BY ColName, ProposalID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET #query = N'SELECT ProposalID, ' + #cols + N' from
(select ProposalID, Amount, ColName from [sbs].[ProposalAmounts]) x
PIVOT
(MAX(Amount)for ColName in (' + #cols + N')) p '
EXEC sp_executesql #query;
This is what I've done so far and I'm confused as to how to declare a table variable that has dynamic columns in it.
This is the result of the query above:
And this is the result of the table I want to perform join statement:
Like Jeroen Mostert commented, you need to make everything dynamic.
I would suggest to put the join inside the dynamic query. Instead of a table variable, I use a common table expression.
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX);
SELECT #cols =
STUFF((SELECT DISTINCT N', ' + QUOTENAME([ColName])
FROM [_tmp_].[ProposalAmounts]
GROUP BY [ColName], [ProposalID]
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'')
SET #query = N'
WITH [CTE_Pivoted_ProposalAmounts] AS
(
SELECT [ProposalID], ' + #cols + N'
FROM
(SELECT [ProposalID], [Amount], [ColName] FROM [sbs].[ProposalAmounts]) x
PIVOT (MAX([Amount]) FOR [ColName] IN (' + #cols + N')) p
)
SELECT *
FROM
[sbs].[OtherTable] ot
INNER JOIN [CTE_Pivoted_ProposalAmounts] ppa ON ppa.[ProposalID] = ot.[ProposalID];
';
EXEC sp_executesql #query;
You need to replace [sbs].[OtherTable] with the actual name of the table you want to join with. And you might also tweak the join criteria and the fields in the SELECT clause. This code here is just a simple example. I assume you will manage to fix the query yourself to make it behave as you expect.
I have a dynamic PIVOT that partially works. It works when I don't request a where clause using a variable but just use a specific number.
I also want to be able to store the results into a temp table.
Is it possible to have a where clause variable in a dynamic pivot and is it possible to save the results to a temp table?
Here is my current query that is not working
declare #CourseID int = 2
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(UnitID)
FROM LMS_Unit_Status where CourseID = #CourseID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT LearnerID, ' + #cols + ' from
(select LearnerID,UnitID,Completed from LMS_Unit_Status where CourseID = #CourseID) as s
pivot
(
min(Completed)
for UnitID in (' + #cols + ')
) p'
execute(#query);
Msg 137, Level 15, State 2, Line 2
Must declare the scalar variable "#CourseID".
Thanks
If #CurseID is a variable parser should know it is a variable and not a string
And since you have no idea how many columns table will have you can simply use select into statement.
set #query = 'SELECT LearnerID, ' + #cols + ' into tempTable from
(select LearnerID,UnitID,Completed from LMS_Unit_Status where CourseID = ' + #CourseID + ') as s
pivot
(
min(Completed)
for UnitID in (' + #cols + ')
) p
select * from tempTable
drop table tempTable'
execute(#query);
Cheers!
I am working on a request to display selected test results from two tables via SSRS. I have developed the dynamic SQL to accomplish this but got stuck when running the stored procedure, as I only receive the first result set.
This stored procedure first queries a tag name table that is used to build columns for the second query... which retrieves the actual desired data. The SP returns the column names but does not return the needed second result set.
I realize this is an ugly solution but our IT group had no input into original database design, so now we're trying to do what we can to help.
Code:
DECLARE #cols as NVARCHAR(MAX), #query1 as NVARCHAR(MAX), #query2 as NVARCHAR(MAX),
#FLOATTABLE NVARCHAR(MAX), #TAGTABLE NVARCHAR(MAX),#startdate as NVARCHAR(MAX),
#ENDDATE AS NVARCHAR(MAX), #results as NVARCHAR(MAX)
set #FLOATTABLE = 'dbo.TRW_TESTER_FLOATTABLE' --for testing purposes only
set #tagtable = 'dbo.TRW_TESTER_TAGTABLE' --for testing purposes only
Set #startdate='2013-12-05' -- for testing purposes only
Set #enddate='2013-12-31' -- for tesying purposes only
set #query2 = 'SELECT STUFF((SELECT DISTINCT '','' +
QUOTENAME(CONVERT(VARCHAR,TagName),'
+ '''"'') FROM ' + #TAGTABLE + ' FOR XML PATH ('''')),1,1,'''')'
EXECUTE sp_executeSQL #query2, #Cols OUTPUT
Set #query1 = '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'
EXECUTE sp_executeSQL #query1, #results OUTPUT
select *
from (
select vtid, convert(date, dtime) as Date from Transaction_tbl where locid = 5
) as vt
pivot (
count(vtid)
for vtid in (select vtid from VType_tbl)
) as pvt
while executing this query am getting error
Incorrect syntax near the keyword 'select'." and Incorrect syntax near
')'.
actually I have one more table,name= Vtype_table , How Can I load all vtid from vtype table in this query? I want to get output depend upon vtid.
Any help greatly appreciated.
Your PIVOT syntax is correct except you are using a SELECT statement inside your PIVOT.
You cannot use a SELECT statement inside the PIVOT IN clause to select column headers. It is required that the columns for the IN clause be known prior to executing the query.
If you are looking to generate a dynamic list of vtid values, then you will need to use dynamic SQL to get the result and the syntax will be similar to the following:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(vtid)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date, ' + #cols + '
from
(
select vtid, convert(date, dtime) as Date
from Transaction_tbl
where locid = 5
) d
pivot
(
count(vtid)
for vtid in (' + #cols + ')
) p '
execute(#query);
Edit, if you want the type names to appear then you should be able to use the following:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(vt_name)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date, ' + #cols + '
from
(
select v.vt_name, convert(date, dtime) as Date
from Transaction_tbl t
inner join VType_tbl v
on t.vtid = v.vtid
where locid = 5
) d
pivot
(
count(vt_name)
for vt_name in (' + #cols + ')
) p '
execute(#query)
Note: I am guessing on the column name for VType_tbl
I am struggling with this query which returns the error: Conversion failed when converting date and/or time from character string.
This is a common error judging from my google searches, but nothing I've tried so far works. I've tried casting #startdate as datetime and varchar and leaving it alone, as in the below example.
I've also tried using convert against the fieldname and the parameter name, although admittedly, I may just be getting the syntax wrong.
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int,
#startdate DATETIME
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname) from FormResponse WHERE FormID = #formid AND value IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse WHERE FormID = ' + CAST(#formid AS VARCHAR(25)) + ' AND createDate > ' + #startdate + '
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
edit: the query works except when I add the bit causing the error:
' AND createDate > ' + #startdate + '
The problem is you are attempting to concatenate a datetime to your varchar sql string. You need to convert it:
convert(varchar(10), #startdate, 120)
So the full code will be:
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int,
#startdate DATETIME
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname) from FormResponse WHERE FormID = #formid AND value IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse
WHERE FormID = ' + CAST(#formid AS VARCHAR(25)) + '
AND createDate > ''' + convert(varchar(10), #startdate, 120) + '''
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
When you dynamically build the SQL Statement, the date value needs to be wrapped in single quotes. Whenever building a dynamic statement, do a SELECT #query and make sure the results look correct.
For your example, you would need to have 'WHERE createdate > ''' + covert(varchar(10), #startdate, 111) + '''
That would output: WHERE createdate > '2013/05/29'
Without the single quotes you would have: WHERE createdate > 2013/05/29