SQL Server Dynamic Pivot Query - sql-server

I am creating a dynamic pivot query that shows the total NetAmount per Week of every Customers within a given date range. The problem is it doesn't ADD ALL the NetAmount within the Week. Here are the data of tblSampleSalesInvoices:
Here is my script.
CREATE PROCEDURE uspSalesWeeklySummary
(
#CustomerId INT,
#FromDate DATETIME,
#ToDate DATETIME
)
AS
SET NOCOUNT ON
DECLARE #Query AS VARCHAR(MAX)
DECLARE #DateStart DATETIME = #FromDate
DECLARE #tmp TABLE ([Date] VARCHAR(MAX))
DECLARE #Month VARCHAR(MAX)
DECLARE #Day VARCHAR(MAX)
DECLARE #ColumnHeader VARCHAR(MAX)
DECLARE #Headers VARCHAR(MAX)
WHILE DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101') <= DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #ToDate), '19050101')
BEGIN
SET #month = DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101'))
SET #day = CAST( DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX) )
SET #ColumnHeader = 'Week ' + CAST(DatePart(WEEK,#DateStart) AS VARCHAR(MAX)) + ' - ' + CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX)) + ' - ' + #month + ' - ' + #day
INSERT INTO #tmp ([Date])
VALUES (#ColumnHeader)
SET #DateStart = DATEADD(DD, 7, #DateStart)
END
SELECT #Headers = ISNULL(#Headers + ',','') + QUOTENAME(t.[Date])
FROM #tmp t
SET #Headers = #Headers + ',[Grand Total]'
SET #Query =
'
DECLARE #CustomerId INT = ' + CAST(#CustomerId AS VARCHAR) + '
DECLARE #FromDate DATETIME = CAST(''' + CAST(#FromDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #ToDate DATETIME = CAST(''' + CAST(#ToDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #Headers VARCHAR(MAX) = ''' + CAST(#Headers AS VARCHAR(MAX)) + '''
SELECT *
FROM
(
SELECT c.CustomerName AS CustomerName,
''Week '' + CAST(DatePart(WEEK,si.TransactionDate) AS VARCHAR(MAX)) + '' - ''
+ CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) + '' - ''
+ CAST(DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) + '' - ''
+ CAST(DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) AS Header,
SUM(si.NetAmount) AS NetAmount
FROM tblSampleSalesInvoices si
LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE (si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101''))
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY c.CustomerName, si.TransactionDate
UNION ALL
SELECT c.CustomerName AS CustomerName,
''Grand Total'' AS Header,
SUM(si.NetAmount) AS NetAmount
FROM tblSampleSalesInvoices si
LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE (si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101''))
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY c.CustomerName
) AS BaseData
PIVOT
(
SUM(NetAmount)
FOR Header IN (' + #Headers + ')
) AS Pivoting'
EXEC (#Query)
GO
EXEC uspSalesWeeklySummary 0,'01/01/2016','02/01/2016'
In this script the SUM of NetAmount will be 10000 only because From the Day of Jan 1, 2016 until Feb 1,2016 only 1 transaction (TR0002) has been made. But when I place Dec 27,2015 and Feb 1,2016 in the parameters. It shows only the NetAmount of TR0001 instead of 25000 which the SUM of TR0001 and TR0002.

If you are looking for week numbers relative to a start date and can create # tables then this might suit
CREATE PROCEDURE uspSalesWeeklySummary
(
#CustomerId INT,
#FromDate DATETIME,
#ToDate DATETIME
)
AS
SET NOCOUNT ON
set datefirst 1
/*
create table tblSampleSalesInvoices (id int,transactionNo int,customerid int,TransactionDate date,netamount int)
insert into tblSampleSalesInvoices values
(1,1,1,'2015-12-29',15000),
(2,2,1,'2016-01-01',15000),
(3,3,2,'2016-03-01',15000),
(4,4,3,'2016-04-01',15000),
(5,5,4,'2016-06-01',15000),
(6,6,1,'2016-09-01',15000),
(7,7,2,'2016-10-01',15000),
(8,8,3,'2016-12-01',15000),
(9,9,4,'2017-01-01',15000),
(10,10,1,'2017-04-01',15000),
(11,11,2,'2017-07-01',15000),
(12,12,3,'2017-10-01',15000),
(13,13,4,'2017-12-01',15000)
*/
--declare #CustomerId INT = 1
--declare #FromDate DATETIME = '2015-12-27'
--declare #ToDate DATETIME = '2016-02-01'
DECLARE #Query AS VARCHAR(MAX)
DECLARE #DateStart DATETIME = #FromDate
IF OBJECT_ID(N'tempdb..#Tempdates') IS NOT NULL
BEGIN
DROP TABLE #Tempdates
END
declare #id int = 0
create table #tempdates (id int,[lodate] date, [hidate] date ,yyyy varchar(4), mm varchar(max), dd int,txt varchar(max))
DECLARE #Month VARCHAR(MAX)
DECLARE #Day VARCHAR(MAX)
DECLARE #ColumnHeader VARCHAR(MAX)
DECLARE #Headers VARCHAR(MAX)
WHILE DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101') <= DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #ToDate), '19050101')
BEGIN
set datefirst 1
SET #month = DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101'))
SET #day = CAST( DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX) )
SET #ColumnHeader = 'Week ' + CAST(DatePart(WEEK,#DateStart) AS VARCHAR(MAX)) + ' - ' +
CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX)) + ' - ' + #month + ' - ' + #day
set #id = #id + 1
insert into #tempdates (id,[lodate],[hidate],yyyy,mm,dd,txt)
values (#id,#datestart,dateadd(dd,6,#datestart),
year(#datestart),
datename(month,#datestart),day(#datestart),
'Week ' + cast(#id as varchar(2)) + ' - ' + cast(datename(month,#datestart) as varchar(max)) + ' - ' + cast(day(#datestart) as varchar(max))
)
SET #DateStart = DATEADD(DD, 7, #DateStart)
END
update #tempdates
set hidate = #todate where id = #id
SELECT #Headers = ISNULL(#Headers + ',','') + QUOTENAME(t.[txt])
FROM #tempdates t
SET #Headers = #Headers + ',[Grand Total]'
--select #headers headers
--select * from #tempdates
set #query =
'
DECLARE #CustomerId INT = ' + CAST(#CustomerId AS VARCHAR) + '
DECLARE #FromDate DATETIME = CAST(''' + CAST(#FromDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #ToDate DATETIME = CAST(''' + CAST(#ToDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #Headers VARCHAR(MAX) = ''' + CAST(#Headers AS VARCHAR(MAX)) + '''
SELECT *
FROM
(
SELECT si.customerid,
t.txt as header,
SUM(si.NetAmount) AS NetAmount
FROM tblsamplesalesinvoices si
left join #tempdates t on si.Transactiondate between lodate and hidate
--LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101'')
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY -- c.CustomerName,
si.customerid
,
t.txt
UNION ALL
SELECT si.CustomerId,
''Grand Total'' AS Header,
SUM(si.NetAmount) AS NetAmount
FROM tblsamplesalesinvoices si
-- LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE (si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101''))
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY si.customerid
) s
PIVOT
(
SUM(NetAmount)
FOR Header IN (' + #Headers + ')
) AS Pivoting'
--select #query
exec (#query)
IF OBJECT_ID(N'tempdb..#Tempdates') IS NOT NULL
BEGIN
DROP TABLE #Tempdates
END
go
Please note dates are UK localised

Related

Creating dynamic table name and table column in SQL Server 2008?

I want to create a dynamic table in SQL Server using dynamic Table name and dynamic Column name. For example:
Table name : 01-02-2015
Column names:
Id 01 02 03.... 28
When I creating a temp table is OK but I want to create a real Table then I use the following script like this, when execute the error occur:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '.01'.
Code:
DECLARE #DynamicSQL as NVARCHAR(max),#TempTableName as nvarchar(max)
DECLARE #TimeSheetDate as DateTime
DECLARE #startDate AS DATETIME --Cursor Local Variables
DECLARE #endDate AS DATETIME
SET #TimeSheetDate = '2015-2-15'
SET #startDate = DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate), 0) -- the first day of month
SET #endDate = DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate) + 1, 0))-- the last day of month
SET #TempTableName = #startDate -- the first day of month
SET #DynamicSQL='CREATE TABLE dbo.'+ quotename(#TempTableName, '[') + '(Id int identity(1,1) not null primary key);';
WHILE (#startDate <= #endDate)
BEGIN
--DECLARE #DynamicSQL VARCHAR(500)
BEGIN
SET #DynamicSQL = 'ALTER TABLE dbo.' + #TempTableName +
' ADD ['+ CONVERT(VARCHAR(2), #startDate, 105) + '] NVARCHAR(max) NULL'
EXECUTE (#DynamicSQL)
END
SET #startDate = DateADD(dd, 1, #startDate)
IF #startDate - 1 = #endDate
BREAK;
END
exec (#DynamicSQL);
If I use this script to create a temp table is OK:
DECLARE #TempTableName as nvarchar(100)
DECLARE #TimeSheetDate as DateTime
DECLARE #startDate AS DATETIME --Cursor Local Variables
DECLARE #endDate AS DATETIME
SET #TimeSheetDate = '2015-2-15'
SET #startDate = DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate), 0)
SET #endDate = DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate) + 1, 0))
SET #TempTableName = DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate), 0)
if exists (select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..##TempTableName'))
DROP TABLE ##TempTableName
CREATE TABLE ##TempTableName(Id int identity(1,1) not null primary key) -- Creating Temp Table
-- Loop to add columns to temp table
WHILE (#startDate <=#endDate)
BEGIN
DECLARE #DynamicSQL VARCHAR(500)
BEGIN
SET #DynamicSQL = 'ALTER TABLE ##TempTableName ADD ['+ CONVERT(VARCHAR(2),#startDate,105) +'] NVARCHAR(100) NULL'
EXECUTE (#DynamicSQL)
END
SET #startDate = DateADD(dd,1,#startDate)
IF #startDate-1 = #endDate
BREAK;
END
SELECT * FROM ##TempTableName
The problem is in your alter table statement.
Change
SET #DynamicSQL = 'ALTER TABLE dbo.' + #TempTableName +
' ADD ['+ CONVERT(VARCHAR(2), #startDate, 105) + '] NVARCHAR(max) NULL'
To
SET #DynamicSQL = 'ALTER TABLE dbo.' + quotename(#TempTableName, '[') +
' ADD ['+ CONVERT(VARCHAR(2), #startDate, 105) + '] NVARCHAR(max) NULL'
This works for my expectation:
ALTER PROCEDURE [dbo].[proc_InsertTimeSheetInit]
#TimeSheetDate as DateTime
AS
BEGIN
DECLARE #DynamicSQL as NVARCHAR(255)
DECLARE #TableName as nvarchar(255)
DECLARE #startDate AS DATETIME
DECLARE #endDate AS DATETIME
DECLARE #dropSQL as NVARCHAR(255)
SET #startDate = DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate), 0) -- the first day of month
SET #endDate = DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, #TimeSheetDate) + 1, 0))-- the last day of month
SET #TableName ='TS'+convert(nvarchar(2), datepart(mm, #TimeSheetDate)) + convert(nvarchar(4), datepart(yyyy, #TimeSheetDate))
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].['+ #TableName+ ']') AND type in (N'U'))
SELECT #dropSQL = 'DROP TABLE dbo.' + QUOTENAME(#TableName) + '';
exec (#dropSQL)
SET #DynamicSQL = 'create table [dbo].[' + #TableName + ']([Id] [int] IDENTITY(1,1) NOT NULL,CONSTRAINT PK_'+#TableName+' PRIMARY KEY CLUSTERED (Id))'
exec (#DynamicSQL)
WHILE (#startDate <= #endDate)
BEGIN
BEGIN
SET #DynamicSQL = 'ALTER TABLE [dbo].[' + #TableName + '] ADD ['+ CONVERT(VARCHAR(2), #startDate, 105) + '] NVARCHAR(50) NULL'
EXECUTE (#DynamicSQL)
END
SET #startDate = DateADD(dd, 1, #startDate)
IF #startDate - 1 = #endDate
BREAK;
END
END

where to use isnull function

I am using dynamic pivot scrip for my report. Below is my script.
DECLARE #Columns VARCHAR(MAX)
set #Columns= ''
SELECT #Columns = #Columns + (QUOTENAME(RTRIM(LTRIM(cast(datename(month, [dates]) as char(15))))+',' + RTRIM(LTRIM(cast(year([dates]) as char(20))))) + ',') FROM efoxsfc.dbo.FTX_FA_Calender
WHERE 1=1
AND CAST(dates AS DATETIME) >= DATEADD(mm, -35 ,DATEADD(m, DATEDIFF(m, 0,GETDATE()), 0))
AND dates <= DATEADD(m, DATEDIFF(m, 0,GETDATE()), 0)
SET #Columns = LEFT(#Columns, LEN(#Columns) - 1)
DECLARE #SQL NVARCHAR(MAX)
set #SQL= ''
SET #SQL =
'WITH BaseData AS
(
select
vendor_code,
RTRIM(LTRIM(cast(datename(month, [CLOSED_DATE]) as char(15))))+'','' + RTRIM(LTRIM(cast(year([CLOSED_DATE]) as char(20)))) as [CLOSED_DATE],
count(vendor_code) as [No. of Case]
from #teamp t WITH (NOLOCK)
where
[CLOSED_DATE] is not null
group by
vendor_code, CLOSED_DATE
)
SELECT *
FROM BaseData
PIVOT
(
sum([No. of Case])
FOR CLOSED_DATE IN (' + #Columns + ')
) AS PivotTable'
EXECUTE sp_executesql #SQL
where will be my isnull function so that will be replace null with zero.
Please advice !!
This is my new Print #SQL
WITH BaseData AS
(
select
vendor_code,
RTRIM(LTRIM(cast(datename(month, [CLOSED_DATE]) as char(15))))+',' + RTRIM(LTRIM(cast(year([CLOSED_DATE]) as char(20)))) as [CLOSED_DATE],
count(vendor_code) as [No. of Case]
from #teamp t WITH (NOLOCK)
where
[CLOSED_DATE] is not null
group by
vendor_code, CLOSED_DATE
)
SELECT ISNULL([November,2012],0)AS[November,2012],ISNULL([December,2012],0)AS[December,2012],ISNULL([January,2013],0)AS[January,2013],ISNULL([February,2013],0)AS[February,2013],ISNULL([March,2013],0)AS[March,2013],ISNULL([April,2013],0)AS[April,2013],ISNULL([May,2013],0)AS[May,2013],ISNULL([June,2013],0)AS[June,2013],ISNULL([July,2013],0)AS[July,2013],ISNULL([August,2013],0)AS[August,2013],ISNULL([September,2013],0)AS[September,2013],ISNULL([October,2013],0)AS[October,2013],ISNULL([November,2013],0)AS[November,2013],ISNULL([December,2013],0)AS[December,2013],ISNULL([January,2014],0)AS[January,2014],ISNULL([February,2014],0)AS[February,2014],ISNULL([March,2014],0)AS[March,2014],ISNULL([April,2014],0)AS[April,2014],ISNULL([May,2014],0)AS[May,2014],ISNULL([June,2014],0)AS[June,2014],ISNULL([July,2014],0)AS[July,2014],ISNULL([August,2014],0)AS[August,2014],ISNULL([September,2014],0)AS[September,2014],ISNULL([October,2014],0)AS[October,2014],ISNULL([November,2014],0)AS[November,2014],ISNULL([December,2014],0)AS[December,2014],ISNULL([January,2015],0)AS[January,2015],ISNULL([February,2015],0)AS[February,2015],ISNULL([March,2015],0)AS[March,2015],ISNULL([April,2015],0)AS[April,2015],ISNULL([May,2015],0)AS[May,2015],ISNULL([June,2015],0)AS[June,2015],ISNULL([July,2015],0)AS[July,2015],ISNULL([August,2015],0)AS[August,2015],ISNULL([September,2015],0)AS[September,2015],ISNULL([October,2015],0)AS[October,2015]FROM BaseData
PIVOT
(
sum([No. of Case])
FOR CLOSED_DATE IN ([November,2012],[December,2012],[January,2013],[February,2013],[March,2013],[April,2013],[May,2013],[June,2013],[July,2013],[August,2013],[September,2013],[October,2013],[November,2013],[December,2013],[January,2014],[February,2014],[March,2014],[April,2014],[May,2014],[June,2014],[July,2014],[August,2014],[September,2014],[October,2014],[November,2014],[December,2014],[January,2015],[February,2015],[March,2015],[April,2015],[May,2015],[June,2015],[July,2015],[August,2015],[September,2015],[October,2015])
) AS PivotTable
This is my new Print #SQL
You need to declare another variable:
DECLARE #Columns2 VARCHAR(MAX) = ''
Then do the main thing:
SELECT #Columns2 = #Columns2 + 'ISNULL(' + (QUOTENAME(RTRIM(LTRIM(cast(datename(month, [dates]) as char(15))))+',' + RTRIM(LTRIM(cast(year([dates]) as char(20))))) + ', 0) AS ' + (QUOTENAME(RTRIM(LTRIM(cast(datename(month, [dates]) as char(15))))+',' + RTRIM(LTRIM(cast(year([dates]) as char(20))))) + ',') FROM efoxsfc.dbo.FTX_FA_Calender
WHERE 1=1
AND CAST(dates AS DATETIME) >= DATEADD(mm, -35 ,DATEADD(m, DATEDIFF(m, 0,GETDATE()), 0))
AND dates <= DATEADD(m, DATEDIFF(m, 0,GETDATE()), 0)
SET #Columns2 = LEFT(#Columns2, LEN(#Columns2) - 1)
Then use it like:
...
SELECT ' + #Columns2 + '
FROM BaseData
PIVOT
...

Conversion failed when converting date in stored procedure

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)

while passing bigger date differnce getting erro in sql

I have stored procedure like this on my DB:
ALTER procedure [dbo].[performance]
(#startdate nvarchar(100), #enddate nvarchar(100)
as begin
declare #date1 nvarchar(100) = convert(varchar, #startdate+' 00:00:00.000', 120)
declare #date2 nvarchar(100) = convert(varchar, #enddate+' 23:59:59.000', 120)
set NOCOUNT on;
select l.LocName,v.Vtype, SUM(DATEDIFF(MI,t.Paydate,t.DelDate)) as TotalDiff,
[dbo].[testfunction](
CONVERT(decimal(10,1), AVG( CONVERT(NUMERIC(18,2), DATEDIFF(SS,t.Paydate,t.DelDate) ) ))) as Average
from Transaction_tbl t
left join VType_tbl v
on t.vtid=v.vtid
left join Location_tbl l
on t.Locid=l.Locid
where t.Locid in
(select t1.Locid from Transaction_tbl t1)
and dtime between '' + #date1 +'' and ''+ #date2 +''
and Status =5
group by v.Vtype,l.LocName,l.Locid order by l.Locid
end
my testfunction ike this:
ALTER FUNCTION [dbo].[testfunction] (#dec NUMERIC(18, 2)) RETURNS Varchar(50)
AS
BEGIN
DECLARE
#hour integer,
#Mns integer,
#second decimal(18,3)
DECLARE #Average Varchar(50)
select #hour=CONVERT(int,#dec/60/60)
SELECT #Mns = convert(int, (#dec / 60) - (#hour * 60 ));
select #second=#dec % 60;
SELECT #Average =
convert(varchar(9), convert(int, #hour)) + ':' +
right('00' + convert(varchar(2), convert(int, #Mns)), 2) + ':' +
right('00' + CONVERT(decimal(10,0), convert(varchar(6), #second)), 6)
RETURN #Average
END
if i pass start date:2013-06-01 and end date:2013-08-01 then getting proper out put
if i pass start date:2010-06-01 and end date:2013-08-01 (bigger date difference) then getting error:
Arithmetic overflow error converting numeric to data type varchar.
i know having some problem with my function.but i am not able find out what is the issue with my function.if any one please help me to find out
try this .. i think your #Mns should be the problem
ALTER FUNCTION [dbo].[testfunction] (#dec NUMERIC(18, 2)) RETURNS Varchar(50)
AS
BEGIN
DECLARE
#hour decimal(18,2),
#Mns decimal(18,2),
#second decimal(18,3)
DECLARE #Average Varchar(50)
select #hour=CONVERT(int,#dec/60/60)
SELECT #Mns = convert(int, (#dec / 60) - (#hour * 60 ));
select #second=#dec % 60;
SELECT #Average =
convert(varchar(9), convert(int, #hour)) + ':' +
right('00' + convert(varchar(8), convert(decimal(18,2), #Mns)), 2) + ':' +
right('00' + CONVERT(decimal(10,0), convert(varchar(10), #second)), 6)
RETURN #Average
END

Arithmetic overflow error converting numeric to data type while executing stored procedure

ALTER procedure [dbo].[performance]
#startdate nvarchar(100),
#enddate nvarchar(100)
as begin
set NOCOUNT on;
select l.LocName,
v.Vtype,
SUM(DATEDIFF(MI,t.Paydate,t.DelDate)) as TotalDiff,
[dbo].[testfunction](CONVERT(decimal(10,1), AVG(
CONVERT(NUMERIC(18,2), DATEDIFF(SS,t.Paydate,t.DelDate) ) ))) as Average
from
Transaction_tbl t
left join
VType_tbl v
on t.vtid=v.vtid
left join
Location_tbl l
on t.Locid=l.Locid
where
t.Locid in(select t1.Locid from Transaction_tbl t1) and
dtime between '' + #startdate +'' and ''+#enddate+'' and
Status =5
group by v.Vtype,l.LocName,l.Locid order by l.Locid
end
also i have one function like this:
ALTER FUNCTION [dbo].[testfunction] (#dec NUMERIC(18, 2)) RETURNS Varchar(50)
AS
BEGIN
DECLARE
#hour integer,
#Mns integer,
#second decimal(18,3)
DECLARE #Average Varchar(50)
select #hour=CONVERT(int,#dec/60/60)
SELECT #Mns = convert(int, (#dec / 60) - (#hour * 60 ));
select #second=#dec % 60;
SELECT #Average =
convert(varchar(9), convert(int, #hour)) + ':' +
right('00' + convert(varchar(2), convert(int, #Mns)), 2) + ':' +
right('00' + CONVERT(decimal(10,0), convert(varchar(6), #second)), 6)
RETURN #Average
END
am passing date like this:2013-01-01 and 2013-05-01
while executing this am getting error:Arithmetic overflow error converting numeric to data type varchar.
Try this one -
ALTER PROCEDURE [dbo].[performance]
#startdate NVARCHAR(100), --<-- try to use date datatype - DATE, DATETIME, ...
#enddate NVARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
SELECT
l.LocName
, v.Vtype
, SUM(DATEDIFF(MI, t.Paydate, t.DelDate)) AS TotalDiff
, [dbo].[testfunction](
CONVERT(DECIMAL(10, 1), AVG(CONVERT(NUMERIC(18, 2), DATEDIFF(SS, t.Paydate, t.DelDate))))
) AS Average
FROM dbo.Transaction_tbl t
LEFT JOIN dbo.VType_tbl v ON t.vtid = v.vtid
LEFT JOIN dbo.Location_tbl l ON t.Locid = l.Locid
WHERE dtime BETWEEN
CAST(#startdate AS DATETIME)
AND
CAST(#enddate AS DATETIME) --<-- possible problem
AND [status] = 5
--AND t.Locid IN (SELECT t1.Locid FROM Transaction_tbl t1) --<-- unnessesary
GROUP BY
v.Vtype
, l.LocName
, l.Locid
ORDER BY l.Locid
END
Update:
ALTER FUNCTION [dbo].[testfunction]
(
#dec NUMERIC(18, 2)
)
RETURNS Varchar(50)
AS BEGIN
DECLARE
#hour BIGINT
, #Mns BIGINT
, #second DECIMAL(18,3)
SELECT
#hour = CONVERT(BIGINT, #dec / 60 / 60)
, #Mns = CONVERT(BIGINT, (#dec / 60) - (#hour * 60))
, #second = #dec % 60
RETURN
CONVERT(VARCHAR(50), CONVERT(BIGINT, #hour)) + ':' + --<-- VARCHAR(9) => VARCHAR(50)
RIGHT('00' + CONVERT(VARCHAR(2), CONVERT(BIGINT, #Mns)), 2) + ':' +
RIGHT('00' + CONVERT(DECIMAL(2, 0), CONVERT(VARCHAR(6), #second)), 6)
END

Resources