alter procedure [dbo].[ParkingDeatailsReport]
#locid INTEGER, #startdate nvarchar(100),#enddate nvarchar(100)
as
begin
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
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 dtime between #startdate and #enddate
and locid = ' + CAST(#locid as varchar(max))
+ ' ) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
execute(#query)
end
I am trying to execute like this:
exec ParkingDeatailsReport 5, '2013-01-01 00:00:00','2013-06-18 23:59:59'
but, I'm getting an error:Must declare the scalar variable "#startdate".
The problem is that you are building SQL in the proc, but you are not using the values in #startdate and #enddate, instead you are passing the string
You need to grab the values of these variables when you build the string - something like:
ALTER PROCEDURE [dbo].[ParkingDeatailsReport]
#locid INTEGER,
#startdate nvarchar(100),
#enddate nvarchar(100)
as
BEGIN
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
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
dtime between ''' + #startdate + ''' and ''' + #enddate + '''
AND locid = ' + CAST(#locid as varchar(max)) + '
) d
PIVOT ( count(Vtype)
FOR Vtype in (' + #cols + ') ) p '
EXECUTE(#query)
END
Related
I have store procedure like this:
ALTER procedure [dbo].[ParkingSummary1] #startdate varchar(100), #enddate varchar(100) as begin
declare #date1 datetime = CONVERT(datetime, #startdate + ' 00:01:00.000', 120);
declare #date2 datetime = CONVERT(datetime, #enddate + ' 23:23:59.000', 120);
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT LocName, ' + #cols + '
from
( select l.LocName,Vtype from Transaction_tbl t join VType_tbl v on t.vtid = v.vtid
join dbo.Location_tbl l on t.locid=l.Locid where dtime between '''+ #date1+''' and '''+#date2+''' and Status = 5 ) d
pivot
(
count(Vtype)
for Vtype in (' + #cols + ')
) p ' exec sys.sp_executesql #query
end
.while am passing startand enddate like this:
#startdate = '2013-08-05',#enddate = '2013-08-08'
am getting error like this:Conversion failed when converting date and/or time from character string.
what is wrong with my stored procedure ? instead of Date1 and date2 if i pass startdate and enddate then it will work.but that time if i given same date then not coming any result
I would use SET DATEFORMAT YMD as the first line of your stored procedure.
ALTER procedure [dbo].[ParkingSummary1] #startdate varchar(100), #enddate varchar(100)
AS
BEGIN
SET DATEFORMAT DMY
declare #date1 datetime = CONVERT(datetime, #startdate + ' 00:01:00.000', 120);
declare #date2 datetime = CONVERT(datetime, #enddate + ' 23:23:59.000', 120);
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT LocName, ' + #cols + '
from
( select l.LocName,Vtype from Transaction_tbl t join VType_tbl v on t.vtid = v.vtid
join dbo.Location_tbl l on t.locid=l.Locid where dtime between '''+ #date1+''' and '''+#date2+''' and Status = 5 ) d
pivot
(
count(Vtype)
for Vtype in (' + #cols + ')
) p ' exec sys.sp_executesql #query
END
I had to replace
declare #date1 datetime = CONVERT(datetime, #startdate + ' 00:01:00.000', 120);
declare #date2 datetime = CONVERT(datetime, #enddate + ' 23:23:59.000', 120);
by
declare #date1 nvarchar(100) = convert(varchar, #startdate+' 00:00:00.000', 120)
declare #date2 nvarchar(100) = convert(varchar, #enddate+' 23:59:59.000', 120)
I have a stored procedure like this:
ALTER PROCEDURE [dbo].[ParkingDeatailsReportcheck]
#locid INTEGER ,
#startdate NVARCHAR(100) ,
#enddate NVARCHAR(100)
AS
BEGIN
DECLARE #cols AS NVARCHAR(MAX) ,
#query AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(Vtype)
FROM VType_tbl
FOR XML PATH('') ,
TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = 'SELECT LocName,Date, ' + #cols
+ ' from ( select l.LocName, v.Vtype, convert(date, dtime) as Date from Transaction_tbl t inner join VType_tbl v on t.vtid = v.vtid
join Location_tbl l on t.locid=l.Locid where locid='
+ CAST(#locid AS VARCHAR(MAX)) + ' and dtime between '''
+ #startdate + ''' and ''' + #enddate + ''' ) d pivot (
count(Vtype)
for Vtype in (' + #cols + ') ) p '
EXECUTE(#query)
END
while executing this stored procedure getting error like this:Ambiguous column name 'locid'.
my expected output like this:
locationname Date Emaar Staff Lost Ticket Normal VIP VVIP
---------- ----------- ----------- ----------- ----------- -----------
Fashion 2013-05-08 1 0 2 0 1
Fashion 2013-05-25 0 0 1 1 0
Fashion 2013-05-27 0 0 17 2 1
You have
join Location_tbl l on t.locid=l.Locid where locid='
change to
join Location_tbl l on t.locid=l.Locid where l.locid='
you need the table alias, it's in the dynamic SQL after the where.
Try to change:
where locid='
to:
where t.locid='
Full query:
ALTER PROCEDURE [dbo].[ParkingDeatailsReportcheck]
#locid INTEGER,
#startdate NVARCHAR(100),
#enddate NVARCHAR(100)
AS
BEGIN
DECLARE #cols AS NVARCHAR(MAX)
,#query AS NVARCHAR(MAX)
SELECT
#cols = STUFF((
SELECT DISTINCT ',' + QUOTENAME(Vtype)
FROM VType_tbl
FOR XML PATH (''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = '
SELECT LocName,Date, ' + #cols + '
from (
select l.LocName, v.Vtype, convert(date, dtime) as Date
from Transaction_tbl t
inner join VType_tbl v on t.vtid = v.vtid
join Location_tbl l on t.locid=l.Locid
where t.locid=' + CAST(#locid AS VARCHAR(MAX)) + '
and dtime between ''' + #startdate + ''' and ''' + #enddate + '''
) d
pivot (
count(Vtype) for Vtype in (' + #cols + ')
) p '
EXECUTE (#query)
END
I have a stored procedure like this:
ALTER procedure [dbo].[ParkingDeatailsReportnew]
#locid INTEGER, #startdate nvarchar(100),#enddate nvarchar(100)
as
begin
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
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 dtime between ''' + #startdate + ''' and ''' + #enddate + '''and locid = ' + (select l.Locid from Location_tbl l)
+ ' ) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
execute(#query)
end
while executing this query I get following error:
expects parameter '#locid', which was not supplied.i want to take all locid from my location table
You Stored Procedure failing to run since you it is expecting get parameters #locid, #StartDate, and #EndDate
EXEC ParkingDeatailsReportnew
#logid = [yourvalue], #StartDate = '[somedate]', #enddate = 'someEndDate'
for example:
EXEC ParkingDeatailsReportnew
#logid = 1234, #StartDate = '2013/08/04 08:01:00 ', #enddate = '2013/08/04 11:21:00'
after you solve this, start solving other issues
--- edit ----
so you need to remove it from the parameters.
ALTER procedure [dbo].[ParkingDeatailsReportnew]
#startdate nvarchar(100),#enddate nvarchar(100)
Why did you have it in the first place?
I doubt that it worked at all execute requires VARCHAR, you have use sp_executesql when you use NVARCHAR
I also think that you have other errors in your logic, but you'll get there later.
Try this one -
ALTER PROCEDURE [dbo].[ParkingDeatailsReportnew]
#locid INTEGER,
#startdate NVARCHAR(100),
#enddate NVARCHAR(100)
AS BEGIN
DECLARE
#cols AS NVARCHAR(MAX)
, #query AS NVARCHAR(MAX)
SELECT #cols = STUFF((
SELECT DISTINCT ',' + QUOTENAME(Vtype)
FROM dbo.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
join VType_tbl v on t.vtid = v.vtid
where dtime between ''' + #startdate + '''
and ''' + #enddate + '''
and locid = ' + CAST(#locid AS VARCHAR(10)) +
' ) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
EXEC sys.sp_executesql #query
END
I have a stored procedure like this:
ALTER procedure [dbo].[ParkingDeatailsReportnew]
#startdate nvarchar(100),
#enddate nvarchar(100)
as
begin
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
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 dtime between ''' + #startdate + ''' and ''' + #enddate +
'''and locid IN ' + (select CAST(l.Locid as varchar(max)) from Location_tbl l)
+ ' ) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
execute(#query)
end
While executing this am getting error like this:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
How i can pass more than 1 value in my sub query?
I'd say your problem lays here:
(select CAST(l.Locid as varchar(max)) from Location_tbl l)
You're trying to form a string from an unknown amount of rows returned from that.
You could just make that part of the string.
Try this one -
ALTER PROCEDURE [dbo].[ParkingDeatailsReportnew]
#startdate NVARCHAR(100),
#enddate NVARCHAR(100)
AS BEGIN
DECLARE
#cols AS NVARCHAR(MAX)
, #query AS NVARCHAR(MAX)
SELECT #cols = STUFF((
SELECT DISTINCT ',' + QUOTENAME(Vtype)
FROM dbo.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
join VType_tbl v on t.vtid = v.vtid
where dtime between ''' + #startdate + ''' and ''' + #enddate + '''
and locid IN (SELECT l.Locid FROM dbo.Location_tbl l)
) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
EXEC sys.sp_executesql #query
END
This executes correctly: (It is weird that I needed to use '' by the date for it to actually execute)
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) FROM [85137_PHY_Long_PG] c FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT statdate, ' + #cols + ' from
(
select statdate, statcolumnname, statcolumnvalue
from [85137_PHY_Long_PG]
) x
pivot
(
min(statcolumnvalue)
for statcolumnname in (' + #cols + ')
) p WHERE statdate BETWEEN ''2012-04-01 12:15:00'' AND ''2012-04-01 12:45:00'' ORDER BY statdate'
execute(#query)
Now I want to replace the dates with variables:
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#from AS NVARCHAR(MAX),
#to AS NVARCHAR(MAX);
set #from = '2012-04-01 12:15:00'
set #to = '2012-04-01 12:45:00'
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) FROM [85137_PHY_Long_PG] c FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT statdate, ' + #cols + ' from
(
select statdate, statcolumnname, statcolumnvalue
from [85137_PHY_Long_PG]
) x
pivot
(
min(statcolumnvalue)
for statcolumnname in (' + #cols + ')
) p WHERE statdate BETWEEN ''+#from+'' AND ''+#to+'' ORDER BY statdate'
execute(#query)
I get the following error:Conversion failed when converting character string to smalldatetime data type
Changing the where statement to the following:
WHERE statdate BETWEEN ''+convert(smalldatetime,#from)+'' AND ''+convert(smalldatetime,#to)+'' ORDER BY statdate'
Still gives me the same error, just can't seem to replace the dates as variables
'' is not weird; it is a notation that enables apostrophes inside varchars.
When concatenating make sure that you are not trying to concatenate anything other than (n)varchars and (n)chars because Sql Server will attempt to convert them to other datatypes; in your case, in smalldatetime. You might avoid this trouble by explicitly converting your parameter dates to nvarchars before/during concatenation, but better solution is to use sp_executesql and parameters.
If you leave parameters inside query:
set #query = 'SELECT statdate, ' + #cols + ' from
(
select statdate, statcolumnname, statcolumnvalue
from [85137_PHY_Long_PG]
) x
pivot
(
min(statcolumnvalue)
for statcolumnname in (' + #cols + ')
) p WHERE statdate BETWEEN #from AND #to ORDER BY statdate'
You can execute it with parameters:
exec sp_executesql #query, N'#from datetime, #to datetime', #from=#from_variable, #to=#to_variable
Where #from_variable and #to_variable are datetime variables defined earlier in batch.
UPDATE:
If your ultimate goal is to wrap this code in stored procedure, here is a template:
create proc MyProc (#dateFrom smalldatetime, #dateTo smalldatetime)
as
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname)
FROM [85137_PHY_Long_PG] c
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT statdate, ' + #cols + ' from
(
select statdate, statcolumnname, statcolumnvalue
from [85137_PHY_Long_PG]
) x
pivot
(
min(statcolumnvalue)
for statcolumnname in (' + #cols + ')
) p WHERE statdate BETWEEN #from AND #to ORDER BY statdate'
exec sp_executesql #query, N'#from smalldatetime, #to smalldatetime', #from=#dateFrom, #to=#dateTo
Herewith the solution:
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#internal_fromdate AS SMALLDATETIME,
#internal_todate AS SMALLDATETIME;
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) FROM [85137_PHY_Long_PG] c FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #internal_fromdate = '2012-04-01 12:15:00';
set #internal_todate = '2012-04-01 12:45:00';
set #query = 'SELECT statdate, ' + #cols + ' from
(
select statdate, statcolumnname, statcolumnvalue
from [85137_PHY_Long_PG]
) x
pivot
(
min(statcolumnvalue)
for statcolumnname in (' + #cols + ')
) p WHERE statdate BETWEEN #FromDate AND #ToDate ORDER BY statdate'
exec sp_executesql #query, N'#FromDate SMALLDATETIME, #ToDate SMALLDATETIME', #FromDate=#internal_fromdate, #ToDate=#internal_todate
UPDATE
Ok, I have tried the following variations:
create proc MyProc9 (#tableName varchar,#dateFrom smalldatetime, #dateTo smalldatetime)
AS
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname)
FROM [85137_PHY_Long_MP] c
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT statdate, ' + #cols + ' from
(
SELECT statdate, statcolumnname, statcolumnvalue
from #table
) x
pivot
(
min(statcolumnvalue)
for statcolumnname in (' + #cols + ')
) p WHERE statdate BETWEEN #from AND #to ORDER BY statdate'
exec sp_executesql #query, N'#table varchar,#from smalldatetime, #to smalldatetime', #table=#tableName,#from=#dateFrom, #to=#dateTo
Error: Must declare the table variable "#table".
Tried '+#tableName+' in the #query string: Incorrect syntax near '8'.
Tried '+QUOTENAME(#tableName)+' in the #query string: Invalid object name '8'.
Tried ['+#tableName+'] in the #query string: Invalid object name '8'.
Tried QUOTENAME(#table) in the #query string: Invalid object name '8'.
Tried [85137_PHY_Long_MP] in the #query string: Works correctly, just want to replace this.
Tried [#tableName] in the #query string: Invalid object name '#tableName'.
Tried #tableName in the #query string: Must declare the table variable "#tableName".
I don't understand how to resolve the problem