Must declare the scalar variable pivot sql query - sql

i am generating attendance report by pivot SQL on the basis of data thought thumb impression but the query shows error
Must declare the scalar variable "#abc".
here is my query
DECLARE #cols NVARCHAR(MAX)
DECLARE #abc NVARCHAR(MAX)
set #abc='00:00'
SELECT
top 1 #cols = COALESCE(#cols + ',[' + CONVERT(varchar, DateIn ,106 )
+ ']','[' + CONVERT(varchar, DateIn ,106) + ']' )
FROM DailyAttendanceMaster where
DateIn between '2019-01-01 00:00:00.000' and '2019-01-01 00:00:00.000'
group by DateIn order by DateIn asc
DECLARE #qry NVARCHAR(4000) SET
#qry = 'SELECT * FROM (SELECT Employee_Master.Employee_Name,
case when convert(char(5), TimeIn, 108)= convert(char(5), #abc, 108) then "A"
else "B"
end "TimeIn" ,
DailyAttendanceMaster.DateIn FROM DailyAttendanceMaster inner
join Employee_Master on Employee_Master.essl_EmpID=DailyAttendanceMaster.EMPID)emp
PIVOT (MAX(TimeIn) FOR DateIn IN (' + #cols + ')) AS stat'
EXEC(#qry)

You need to pass variable:
EXEC sp_executesql #qry, N'#abc NVARCHAR(MAX)', #abc

Related

Pivoting table gives error : Must declare the scalar variable #start1

Error :
Must declare the scalar variable "#start1".
Here is my query, I have two functions and am trying to pivot the data. The first function dbo.fxnExample accepts parameters is good but the second function dbo.fxnExample2 does not accept the parameters value, it pass 0 as the value.
ALTER proc [dbo].[SpTimesheetCrossTableFormat]
#start NVARCHAR(20),
#end NVARCHAR(20)
AS
BEGIN
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX),
#PivotColumnNames AS NVARCHAR(MAX),
#PivotSelectColumnNames AS NVARCHAR(MAX)
DECLARE #start1 as nvarchar(20)=#start
DECLARE #start2 as nvarchar(20)=#end
--Get DISTINCT values of the PIVOT Column
SELECT #PivotColumnNames= convert(NVARCHAR(max),(ISNULL(#PivotColumnNames + ',','')))
+ CONVERT(NVARCHAR(max),(QUOTENAME(project_name)))
FROM (SELECT DISTINCT project_name FROM dbo.fxnExample(#start,#end)) AS project_name
--Get DISTINCT values of the PIVOT Column with isnull
SELECT #PivotSelectColumnNames
= ISNULL(#PivotSelectColumnNames + ',','')
+ 'ISNULL(' + QUOTENAME(project_name) + ', 0) AS '
+ QUOTENAME(project_name)
FROM (SELECT DISTINCT project_name FROM dbo.fxnExample(#start,#end)) AS project_name
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT d, user_name, ' + #PivotSelectColumnNames + '
FROM dbo.fxnExample2(#start1,#start2)
PIVOT(SUM(mins)
FOR project_name IN (' + #PivotColumnNames + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
END
Here is the function :
CREATE FUNCTION [dbo].[fxnExample2] (#StartDate NVARCHAR(20),#EndDate NVARCHAR(20))
RETURNS TABLE
AS
RETURN
(
SELECT user_details.user_name,project_details.name as project_name,
--(ISNULL( DATEDIFF(mi,convert(datetime,punch_in,108), CONVERT(datetime,punch_out,108)),0)) as mins
[hours] as mins ,#StartDate as d
FROM timesheets
JOIN user_details
ON timesheets.user_id=user_details.id
JOIN project_details
ON timesheets.project_id=project_details.id
WHERE CONVERT(date, timesheets.tdate, 103) BETWEEN CONVERT(date, #StartDate, 103) and convert(date, #EndDate, 103)
--where CONVERT(date, tdate, 103) BETWEEN CONVERT(date, '15/08/2019', 103) AND CONVERT(date, '15/08/2019', 103)
)`
fnexample function
`CREATE FUNCTION [dbo].[fxnExample] (#StartDate nvarchar(20),#EndDate nvarchar(20))
RETURNS TABLE
AS
RETURN
(
SELECT user_details.user_name,project_details.name as project_name,
--(ISNULL( DATEDIFF(mi,CONVERT(datetime,punch_in,108), CONVERT(datetime,punch_out,108)),0)) as mins
[hours] as mins
FROM timesheets
JOIN user_details
ON timesheets.user_id=user_details.id
JOIN project_details
ON timesheets.project_id=project_details.id
WHERE CONVERT(date, tdate, 103) BETWEEN CONVERT(date, #StartDate, 103) AND CONVERT(date, #EndDate, 103)
--where CONVERT(date, tdate, 103) BETWEEN CONVERT(date, '05/08/2020', 103) AND CONVERT(date, '05/08/2019', 103)
)
Explanations about your error:
You are trying to execute a dynamic T-SQL statement using sp_executesql. If this statement contains parameters, you need to pass definitions of these parameters and their values to sp_executesql.
In your case, execute your statement in the following way:
EXEC sp_executesql
#DynamicPivotQuery,
N'#start1 as nvarchar(20), #start2 as nvarchar(20)',
#start1,
#start2
Notes:
It's good to check the result from sp_executesql call and optionally print this statement before the execution:
DECLARE #err int
PRINT #DynamicPivotQuery
EXEC #err = sp_executesql
#DynamicPivotQuery,
N'#start1 as nvarchar(20), #start2 as nvarchar(20)',
#start1,
#start2
IF #err = 0 PRINT 'OK' ELSE PRINT 'Error'

how to set space between two pivot column

query pivot with two word with space in column
DECLARE #cols NVARCHAR(MAX) SELECT
top 24 #cols = COALESCE(#cols + ',[' + CONVERT(varchar, DateIn ,21 ) + ']','[' + CONVERT(varchar, DateIn ,21) + ']' )
FROM DailyAttendanceMaster where DateIn between '2018-10-01 00:00:00.000' and '2018-10-24 00:00:00.000'
DECLARE #qry NVARCHAR(4000) SET
#qry = 'SELECT * FROM (SELECT Employee_Master.Employee_Name, convert(char(5), TimeIn, 108)+ + convert(char(5), TimeOutD, 108)TimeIn , DailyAttendanceMaster.DateIn FROM DailyAttendanceMaster inner join Employee_Master on Employee_Master.essl_EmpID=DailyAttendanceMaster.EMPID)emp
PIVOT (MAX(TimeIn) FOR DateIn IN (' + #cols + ')) AS stat'
EXEC(#qry)
here is my pivot query i am concatenate two column that is TimeIn and TimeOutD it work correct but i want sapce between two column so how can i do it
enter image description here

Dynamic query based on datetime parameter

I have a SQL Server database with date representation name like below & each database contains table A (table A having column like id, datetime, value, value1 etc).
Jan2018
Feb2018
Mar2018 and so on..
My search condition is user selected date (eg. from 01-Jan-2018 to 01-Jun-2018) which I am passing to a stored procedure (max range 6 month). I want to generate dynamic query to get data from these database based on datetime passed.
How to achieve this functionality as I found difficult to implement.
Can you try this query
CREATE PROCEDURE Myproc #FromDate DATE,
#ToDate DATE
AS
BEGIN
DECLARE #SQL NVARCHAR(max)='',
#unionall VARCHAR(10)=''
WITH cte
AS (SELECT #FromDate dt,
1 mont
UNION ALL
SELECT Dateadd(month, 1, dt) dt,
mont + 1 mont
FROM cte
WHERE mont < Datediff(month, #FromDate, #ToDate)
)
SELECT #SQL += #unionall + '
select * from ['
+ LEFT (CONVERT(VARCHAR, Datename (month, dt )), 3)
+ CONVERT (VARCHAR, Year (dt))
+ '].[dbo].[tablename]',
#unionall = ' union all '
FROM cte
PRINT #SQL
EXECUTE( #SQL)
END
You should query sys.databases to find a database you need.
Then, as you can only use static declarations of databases, you should create a textual select statement and execute it.
I tried it on my dbs and it worked.
This is my code:
declare #date varchar(20) = '2018'
declare #dbName varchar(20)
declare #sSql varchar(200)
declare #sConditions varchar(20) = ''
Set #dbName = (SELECT name FROM master.sys.databases
where name like '%' + #date + '%')
print #dbName
Select #sSql = 'Select * From ' + #dbName + '.dbo.MyDB '
--+ ' Where ' + #sConditions
Execute (#sSql)
if you need to query all that fit year. do like this:
declare #date varchar(20) = 'a'
SELECT name Into #dbnames
FROM master.sys.databases
where name like '%' + #date + '%'
this brings a table of all sutable dbs. then query each one of them using loop. like cursor
Are you looking for
CREATE PROCEDURE MyProc
#FromDate DATE,
#ToDate DATE,
#Target SysName
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX)= N'SELECT * FROM [' +
#Target +
'] WHERE [Dates] >= #FromDate AND [Dates] <= #ToDate';
EXECUTE sp_executesql #SQL,
N'#FromDate DATE, #ToDate DATE',
#FromDate,
#ToDate;
END
Demo
As I now understand what you are trying to do, you can
CREATE PROCEDURE ProcName
#FromDate DATE,
#ToDate DATE
AS
BEGIN
--Declare a variable to hold the Dynamic SQL
DECLARE #SQL NVARCHAR(MAX) = N'';
--Generate the databases names
WITH CTE AS
(
SELECT #FromDate D,
1 N
UNION ALL
SELECT DATEADD(Month, N, #FromDate),
N + 1
FROM CTE
WHERE N <= DATEDIFF(Month, #FromDate, #ToDate)
)
--Build the SELECT statement
SELECT #SQL = #SQL+
N'SELECT * FROM ['+
CONVERT(VARCHAR(3), D, 100)+
CAST(YEAR(D) AS VARCHAR(4))+
'].dbo.TableName UNION ALL ' --Or UNION as you want
FROM CTE;
--Remove the last UNION ALL
SET #SQL = LEFT(#SQL, LEN(#SQL) - 10); --If UNION then just -6
--Execute the statement
EXECUTE sp_executesql #SQL;
END

Operand type clash: date is incompatible with int While selecting rows

ALTER PROCEDURE [dbo].[Expense_monthly_report] #start_date VARCHAR(100),
#end_date VARCHAR(100)
AS
BEGIN
DECLARE #SQLQuery AS NVARCHAR(max)
DECLARE #PivotColumns AS NVARCHAR(max)
SET nocount ON;
SELECT #PivotColumns = COALESCE(#PivotColumns + ',', '')
+ Quotename( date_of_expp)
FROM (SELECT DISTINCT Month(date_of_exp) AS date_of_expp
FROM [dbo].[tbl_exp_details]
WHERE date_of_exp >= #start_date
AND date_of_exp <= #end_date) AS PivotExample
SET #SQLQuery = N'SELECT p.part_id,' + #PivotColumns
+ ',total_amount FROM (SELECT part_id,month(date_of_exp) as month_of_exp,exp_amount FROM [dbo].[tbl_exp_details]) as tbl PIVOT( sum(exp_amount) FOR month_of_exp IN ('
+ #PivotColumns
+ ')) AS P join (SELECT part_id,sum(exp_amount) as total_amount FROM [dbo].[tbl_exp_details] where date_of_exp>='
+ #start_date + ' and date_of_exp<=' + #end_date
+ ' group by part_id) as la on p.part_id=la.part_id'
EXEC Sp_executesql #SQLQuery
END
I am getting error
date incompatible with int
. Help me to find out the problem.
You have not delimited the date values in the dynamic query.
So
date_of_exp<=' + #end_date
becomes
date_of_exp<= 2017-07-19
which evaluates to this, and int won't implicitly convert to date
date_of_exp <= 1991
The correct way to use Sp_executesql and fix this is:
SET #SQLQuery = N'SELECT p.part_id,' + #PivotColumns
+ ',total_amount FROM (SELECT part_id,month(date_of_exp) as month_of_exp,exp_amount FROM [dbo].[tbl_exp_details]) as tbl PIVOT( sum(exp_amount) FOR month_of_exp IN ('
+ #PivotColumns
+ ')) AS P join (SELECT part_id,sum(exp_amount) as total_amount FROM [dbo].[tbl_exp_details] where date_of_exp>= #start_date and date_of_exp<=#end_date '
+ ' group by part_id) as la on p.part_id=la.part_id'
EXEC Sp_executesql #SQLQuery,
N'#start_date date, #end_date date',
#start_date,
#end_date

How do I name a column as a date value

the results look like this but wher the column name says 'Today' I want it to be todays date.
Try this technique:
declare #dt datetime
declare #sql varchar(100)
set #dt = getdate()
set #sql = 'select 1 as [ ' + convert( varchar(25),#dt,120) + ']'
exec (#sql)
In your Case:
declare #dt datetime
declare #sql varchar(100)
set #dt = getdate()
set #sql = 'select 0 as [ ' + convert( varchar(25),#dt,120) + ']'
exec (#sql)
I would return an integer representing a day offset and parse it in the client, failing that you are going to have to use dynamic SQL or do something with the underlying column name itself;;
declare #sql nvarchar(128) = '
select
col1,
col2,
0 as [' + cast(getdate() as nvarchar(32)) + ']
from T'
exec(#sql)
Or
--today
declare #now varchar(32) = cast(getdate() as varchar(32))
--result to temp table
select col1, col2, 0 as [Now] into #T from TheTable
--rename col
exec tempdb..sp_rename '#T.Now', #now, 'COLUMN'
--select
select * from #T