SSRS String -vs- Data Integer - reporting-services

I am working on a SSRS report and using a parameter that allows you to choose multiple options. However, when I do this I get an error that states:
Error Converting Data Type nVarChar to Int.
The data in the database is an Integer. The parameter is set up as an Integer and it works great when only choosing one option. The issue comes when I choose multiple options.
My co-worker came up with one work-around but I would like something a little more elegant and easier to plug in if possible.
Here is his work-around:
ALTER PROCEDURE [dbo].[DtaPrep_MktgClients]
#BegDate date = NULL
, #EndDate date = NULL
, #Species varchar(50) = 'canine,feline,K9,'
 , #HospList varchar(500) = NULL
This is where the hospmastid string gets converted into a temp table
/*
--===================================--
HOSPITALS SETUP
--===================================--
*/
If #HospList IS NOT NULL
BEGIN
DECLARE #WorkHospList varchar(500)
SET #WorkHospList = #HospList
;
CREATE TABLE #HospList
( HospID smallint NULL )
SET #CommaLoc = charindex(',', #WorkHospList)
WHILE #CommaLoc > 1
BEGIN
SET #curVal = LEFT(#WorkHospList, #commaloc-1 )
INSERT INTO
#HospList( HospID )
SELECT #curVal
SET #WorkHospList = substring( #WorkHospList, #commaloc+1, len(#WorkHospList) )
SET #CommaLoc = charindex(',', #WorkHospList)
END
END
This is using the temp table to accomplish the same thing as a “WHERE Hospmastid IN (101,102,103)…”
Method 1
SELECT
HospitalMasterID
, ClientID
, FirstName
, LastName
FROM
Client
WHERE
HospitalMasterID IN (Select HospID From #HospList )
Needless to say, I am sure there is a better way to accomplish this. If anyone has any ideas, please let me know.
Here is the full Query I am now using. But it is not selecting anything so there is an issue with the Created Table.
USE [xxxxx]
GO
/****** Object: StoredProcedure [dbo].[PriceErosion] Script Date: 11/26/2013 8:26:33 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
-- =============================================
-- Author:
-- Create date: 11/25/2013
-- Description: Determines the products in which the price was lowered and revenue lost during a set time period.
-- =============================================
*/
--#StartDate as Date = Null
--,#EndDate as Date = Null
--,#CurDate as Date = Null
--,#Hospital as VarChar = Null
--,#Division as Int = Null
Declare #StartDate as Date = Null
Declare #EndDate as Date = Null
Declare #Hospital as Int = Null
Declare #Division as Int = Null
DECLARE #curDate Date = Null
SET #curDate = GETDATE()
Set #StartDate = CASE WHEN #StartDate IS NULL THEN DATEADD(dd, -31, Dateadd(dd, -1, #curdate) ) ELSE #StartDate END
Set #EndDate = CASE WHEN #EndDate IS NULL THEN Dateadd(dd, -1, #curdate) ELSE #EndDate END
Set #Hospital = Case When #Hospital IS Null Then '3' Else #Hospital End;
IF OBJECT_ID('tempdb.dbo.#HospList') IS NOT NULL DROP TABLE #HospList ;
If #Hospital IS NOT NULL
BEGIN
DECLARE #WorkHospList varchar(500)
Declare #CommaLoc as Int
Declare #curVal as int
SET #WorkHospList = #Hospital
;
CREATE TABLE #HospList
( HospID smallint NULL )
SET #CommaLoc = charindex(',', #WorkHospList)
WHILE #CommaLoc > 1
BEGIN
SET #curVal = LEFT(#WorkHospList, #commaloc-1 )
INSERT INTO
#HospList( HospID )
SELECT #curVal
SET #WorkHospList = substring( #WorkHospList, #commaloc+1, len(#WorkHospList) )
SET #CommaLoc = charindex(',', #WorkHospList)
END
END
Begin
-- Sets the Baseline Price Date in the PriceChangeHistory Table.
With PC1
as
(Select
HospitalMasterID
,TxnCode
,UserInfoMasterID
,Active
,min(TxnDateTime) as StartingDate
From
PriceChangeHistory
Where
TxnDateTime Between #StartDate and #EndDate
Group By
HospitalMasterID, TxnCode, UserInfoMasterID, Active)
-- Gets the Baseline Price for the period from the PriceChangeHistory Table
,PC
as
(Select
PC1.HospitalMasterID
,PC1.TxnCode
,PC1.UserInfoMasterID
,PC1.Active
,Cast (PC1.StartingDate as Date) as StartingDate
,PC2.OldPrice as StartingPrice
,PC2.NewPrice
,PC2.TxnSubType
From
PC1
Inner Join
PriceChangeHistory as PC2
On
PC1.HospitalMasterID = PC2.HospitalMasterID
and
PC1.TxnCode = PC2.TxnCode
and
PC1.StartingDate = PC2.TxnDateTime
Where
PC2.OldPrice > PC2.NewPrice)
--MedicalHistory Information
,MH
as
(Select
HospitalMasterID
,PatientID
,TxnDate
,TxnCode
,Description
,ListAmount
,ExtendedAmount
,TxnType
,Quantity
,(Case
When Quantity <> '1' Then (ListAmount/Quantity)
Else ListAmount
End) as UnitPrice
From
MedicalHistory
Where
TxnDate Between #StartDate and #EndDate
and
_IsServOrITem = 1)
-- Determines the Revenue lost per each sale, also reduces the results to only those items where the Price was lowered not raised.
,RL
as
(Select
PC.HospitalMasterID
,MH.PatientID
,PC.TxnCode
,PC.TxnSubType
,MH.Description
,PC.UserInfoMasterID as ChangedByUserID
,MH.TxnDate
,PC.StartingPrice
,Cast (MH.UnitPrice as Money) as UnitPrice
,Cast ((StartingPrice - UnitPrice) as Money) as RevenueLost
From
PC
Left OUter Join
MH
on
PC.HospitalMasterID = MH.HospitalMasterID
and
PC.TxnCode = MH.TxnCode
Where
PC.StartingPrice > MH.UnitPrice)
--- Determine the name of the tech changing the prices.
,UI
as
(Select
HospitalMasterID
,UserInfoMasterID
,Name
From
UserInfo)
--- Get the Division and Hospital Name for each Hospital.
,HODI
as
(Select
DI.DivisionID
,DI.DivisionName
,HO.HospMastID
,HO.HospCode
,HO.HospName
From
ref_Hospital as HO
inner Join
ref_Division as DI
on
HO.DivisionID = DI.DivisionID)
,HI
as
(Select
HODI.DivisionID
,HODI.DivisionName
,RL.HospitalMasterID
,HODI.HospCode
,HODI.HospName
,RL.PatientID
,RL.TxnCode
,RL.TxnSubType
,RL.Description
,RL.ChangedByUserID
,RL.TxnDate
,RL.StartingPrice
,RL.UnitPrice
,RL.RevenueLost
From
RL
Left Outer Join
HODI
ON
RL.HospitalMasterID = HODI.HospMastID
Where
TXNDate Between #StartDate and #EndDate)
Select
*
From
HI
Where
HospitalMasterID in (Select HospID from #Hosplist)
Order By
HOspitalMasterID
end

Prior to SQL Server 2008, the standard way to filter by one or more values was to pass an XML document to the Stored Procedure and join on it. In this case, you could pass the data as a string with the integers separated by commas, then convert that into an XML document, then join on the XML. So you should change the multiselect in SSRS to a text datatype. Here's a post that shows you how to open an XML document: http://blog.sqlauthority.com/2009/02/13/sql-server-simple-example-of-reading-xml-file-using-t-sql/
SQL Server 2008 lets you use table-valued parameters, but again, it might be best to pass the data as a string of comma separated integers and then let the stored procedure put the data into a table-valued parameter, and then join on that. Here's a post that describes how to use table valued parameters: http://blog.sqlauthority.com/2008/08/31/sql-server-table-valued-parameters-in-sql-server-2008/

Related

VB.Net Daily Time Record MySQL

Good day, I have a problem regarding MySQL queries. I want to create a daily time record output but my problem is on making queries. What I want is that when a record have the same id and date it must be updated otherwise it will insert a new record. These are some of screenshots of table properties
CREATE PROCEDURE dbo.EditGrade
#Id int
,#TimeIn datetime
,#TimeOut datetime
,#Existing bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #CurrentTimeIn as datetime
DECLARE #CurrentId as int
SELECT #CurrentId = Id
FROM tblAttendance
WHERE TimeIn = #TimeIn
IF (#CurrentId <> #Id)
BEGIN
IF (SELECT COUNT(ISNULL(Id,0))
FROM tblAttendance
WHERE TimeIn = #TimeIn
SET #Existing = 0
ELSE
SET #Existing = 1
END
ELSE
BEGIN
SET #Existing = 0
END
IF #Name = ''
SET #Name = null
IF (#Existing = 0)
UPDATE tblAttendance
SET TimeIn = #TimeIn
--other column values here
WHERE Id = #Id
ELSE
--INSERT FROM tblAttendance query here
END
GO
this is from stored procedure of ms sql, you can just convert it into mysql version.
take note, datetime types also checks the seconds, so don't include the seconds as much as possible or it will render as NOT THE SAME (e.g time in = 10:00:01 and time out is 10:00:02 will be rendered as NOT THE SAME)

How many equal days are between two date ranges, SQL

I have table with date ranges, like this:
DATE DATE2
14.03.2013 17.03.2013
13.04.2013 02.05.2013
I have to create a procedure, that returns day count that is equal to two date ranges, one which is in the table and another one.
Forexample, I have date range in the table like this 14.03.2013 - 17.03.2013 and another one, which is declared in procedure like this 02.03.2013 - 16.03.2013, so in this case day count would be 3, because, both date ranges have dates between 14.03.2013 and 16.03.2013.
suppose your table is called daterange and you have parameters defined #param1 and param2 in your procedure then something on these lines should work:
set #param1 := cast('2013-03-14' as date);
set #param2 := cast('2013-03-16' as date);
select
datediff(least(date2,#param2),#param1)+1
from daterange where #param1 between date1 and date2
See example in sqlfiddle
You should be able to adapt this T-SQL function to MySQL
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_RPT_OverlappingDateRangesDays]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fu_RPT_OverlappingDateRangesDays]
GO
-- ======================================================================================================================
-- Author: Stefan Steiger
-- ALTER date: 11.06.2015
-- Alter date: 11.06.2015
-- Description: Calculate the number of overlapping days in two date-ranges
-- http://stackoverflow.com/questions/20836429/how-to-gets-the-number-of-overlapping-days-between-2-ranges
-- ======================================================================================================================
-- DECLARE #firstStart datetime
-- DECLARE #firstEnd datetime
-- DECLARE #secondStart datetime
-- DECLARE #secondEnd datetime
-- SET #firstStart = '01.01.2015'
-- SET #firstEnd = '31.01.2015'
-- SET #secondStart = '15.01.2014'
-- SET #secondEnd = '15.02.2015'
-- SELECT dbo.fu_RPT_OverlappingDateRangesDays( #firstStart, #firstEnd, #secondStart, #secondEnd )
CREATE FUNCTION [dbo].[fu_RPT_OverlappingDateRangesDays]
(
#firstStart datetime
,#firstEnd datetime
,#secondStart datetime
,#secondEnd datetime
)
RETURNS integer
AS
BEGIN
DECLARE #maxStart datetime
DECLARE #minEnd datetime
DECLARE #interval int
IF #firstStart IS NULL OR #firstEnd IS NULL OR #secondStart IS NULL OR #secondEnd IS NULL
-- RETURN 0
RETURN NULL
IF #firstEnd < #firstStart
RETURN 0
IF #secondEnd < #secondStart
RETURN 0
SET #maxStart = #secondStart
SET #minEnd = #secondEnd
IF #firstStart > #secondStart
SET #maxStart = #firstStart
IF #firstEnd < #secondEnd
SET #minEnd = #firstEnd
-- PRINT #maxStart
-- PRINT #minEnd
--SET #interval = DATEDIFF(DAY, #maxStart, #minEnd) + 1
SET #interval = {fn timestampdiff(SQL_TSI_DAY, #maxStart, #minEnd)} + 1
IF #interval < 0
SET #interval = 0
-- PRINT #interval
RETURN #interval
END
GO

Searching - Stored Procedure - DateTime variable - Easy Resolution?

I am trying to create a stored procedure that when entered the three variables:
#Bank_Number = 530
#Branch_Number = 002
#Date_From = 10/28/2014
#Date_To = 10/29/2014
It will return all records between the Date_From and Date_To dates that match the Bank_Number and Branch_Number.
The code I have here is incorrect slightly I'm not sure how to proceed.
ALTER PROCEDURE [dbo].[Something_Proc]
#Bank_Number varchar(3),
#Branch_Number varchar(3),
#Date_From datetime,
#Date_To datetime
AS
BEGIN
SET NOCOUNT ON;
DECLARE #bankNumber varchar(3) = #Bank_Number,
#branchNumber varchar(3) = #Branch_Number,
#dateCreated datetime = #Date_From,
#dateCreated datetime = #Date_To
SELECT DISTINCT
A.bankNumber,
A.branchNumber,
CONVERT(VARCHAR(8), A.dateCreated, 1)
FROM
dbo.(table from picture) A
WHERE
(#bankNumber IS NULL OR Bank_Number LIKE #bankNumber + '%')
AND (#branchNumber IS NULL OR Branch_Number LIKE #branchNumber + '%')
AND (#dateCreated IS NULL OR (MONTH(dateCreated) = MONTH(#dateCreated)
AND DAY(dateCreated) = DAY(#dateCreated)
AND YEAR(dateCreated) = YEAR(#dateCreated)))
END
Can't you just use something like this?
WHERE
(#bankNumber IS NULL OR Bank_Number LIKE #bankNumber + '%')
AND (#branchNumber IS NULL OR Branch_Number LIKE #branchNumber + '%')
AND (#Date_From IS NULL OR #Date_From <= DateCreated)
AND (#Date_To IS NULL OR DateCreated <= #DateTo)
Basically, either your #Date_From and #Date_To parameters are NULL (then that parameters isn't used in any way), or if it's not null, then it's used to compare DateCreated to be equal or larger than #Date_From, and equal or smaller than #Date_To ....

Stored Procedure Can't drop temp table it don't exist

SQL Server 2008
This is a continuation of my last question. Now I'm trying to create a stored procedure, however I can't execute it. When I execute it, an error message displays
"Cannot drop the table #MyReport", because it does not exist or you do not have permissions.
Please guide me in the right direction.
Below is my stored Procedure
Create PROCEDURE [dbo].[SEL_MyReport]
(
#employeeid int,
#date1 datetime,
#date2 datetime
)
AS
BEGIN
drop table #MyReport
Create Table #MyReport
(
employeeid int,
name varchar(30),
department varchar(30),
checkTime datetime
)
if (#employeeid > 0)
Begin
INSERT INTO #MyReport (employeeid,name, department, checkTime)
select emp.EmpolyeeID, emp.Name,dep.DeptName,tm.checkTime
from TimeInOut tm
left join Employee emp on emp.EmpolyeeId = tm.EmployeeId
left join Department dep on dep.DeptID = emp.defaultDeptID
where (DATEDIFF(s,#date1,tm.checktime) >=0
and DATEDIFF(s,#date2,tm.checktime)<=0) and emp.employeeID = #employeeid
SELECT
employeeid
,name
,department
,[Time In] = MIN(checkTime)
,[Time Out] = MAX(checkTime)
FROM #MyReport
GROUP BY employeeid,name, department, CAST(checktime AS DATE)
End
Else
Begin
INSERT INTO #MyReport (employeeid,name, department, checkTime)
select emp.EmpolyeeID, emp.Name,dep.DeptName,tm.checkTime
from TimeInOut tm
left join Employee emp on emp.EmpolyeeId = tm.EmployeeId
left join Department dep on dep.DeptID = emp.defaultDeptID
where (DATEDIFF(s,#date1,tm.checktime) >=0
and DATEDIFF(s,#date2,tm.checktime)<=0)
SELECT
employeeid
,name
,department
,[Time In] = MIN(checkTime)
,[Time Out] = MAX(checkTime)
FROM #MyReport
GROUP BY employeeid,name, department, CAST(checktime AS DATE)
End
END
Go
exec SEL_MyReport('639','05/01/2014','05/08/2014')
There is quite a bit I would change - here is the code.
You will notice
branching logic (if #employeeid > 0) has been replaced by a slightly more verbose WHERE clause
no need for #tables as far as I can tell, the SELECT should suffice
Unfortunately, I do not have anything to test against, but you should understand the general impression of it.
Further, your date filtering seemed quite strange, so I assumed you may have meant something else - I could be mistaken. Either way, the way the date filtering is now done is SARGable
CREATE PROCEDURE [dbo].[SEL_MyReport]
(
#employeeid INT,
#date1 DATETIME,
#date2 DATETIME
)
AS
BEGIN
SET NOCOUNT ON;
SELECT emp.EmpolyeeID
,emp.Name
,dep.DeptName
,[Time In] = MIN(tm.checkTime)
,[Time Out] = MAX(tm.checkTime)
FROM TimeInOut tm
LEFT
JOIN Employee emp on emp.EmpolyeeId = tm.EmployeeId
LEFT
JOIN Department dep on dep.DeptID = emp.defaultDeptID
WHERE tm.checktime >= #date1
AND tm.checktime <= #date2
/***********************************************************************************************************
* I've assumed what you may be trying to express, above
* You might also want to look at the BETWEEN() operator, remembering that it is inclusive in its behaviour
* (DATEDIFF(s,#date1,tm.checktime) >=0
* AND DATEDIFF(s,#date2,tm.checktime)<=0)
***********************************************************************************************************/
AND (emp.employeeID = #employeeid OR #employeeid <= 0)
GROUP BY emp.EmpolyeeID, emp.name, dep.department, CAST(tm.checktime AS DATE)
END
GO
Well, since the very first step of your Stored Procedure attempts to drop a table, this will obviously result in an error if that table does not exist.
To work around this, make sure you check whether the table exists, before you drop it:
IF OBJECT_ID('tempdb..#MyReport') IS NOT NULL DROP
TABLE #MyReport

Stripping the time out of datetime SQL Server 2005

I think I'm going crazy here.
I am trying to do a SP on SQL Server 2005 which takes a date, looks it up in another table and assigns a period number and week number (for financial calendar purposes).
The output needs to hold the date as a string, rather than datetime.
I simply CANNOT get the date to show without the time behind it.
I have tried a couple of methods:
select cast(floor(cast(#CalcDate as float)) as datetime)
I have made a function which converts it into a string and puts it back out again:
CREATE FUNCTION dbo.DateToVarchar (#DateIn datetime)
RETURNS varchar(10)
AS
BEGIN
declare #DD [varchar] (2)
declare #MM [varchar] (2)
declare #YYYY [varchar] (4)
declare #DateOut [varchar] (10)
declare #DDLen [int]
declare #MMLen [int]
set #DD = datepart(dd,#DateIn)
set #DDLen = len(#DD)
set #DD = (case when #DDLen < 2 then '0' + #DD else #DD end)
set #MM = datepart(mm,#DateIn)
set #MMLen = len(#MM)
set #MM = (case when #MMLen < 2 then '0' + #MM else #MM end)
set #YYYY = datepart(yyyy,#DateIn)
set #DateOut = #YYYY + '-' + #MM + '-' + #DD
return #DateOut
END
When I run the above function outside of the SP I get the date back just fine. When I run it through the SP it comes back as 2012-12-30 00:00:00.000
The variable #CalcDate is declared as a varchar(10)
Any ideas?
Thanks in advance
EDIT
Here is the body of the SP so far:
declare #StartDate [datetime]
, #EndDate [Datetime]
, #CalcDate [datetime] --This number will change in the WHILE loop to reflect the increment of days
, #Week [varchar]
, #Period [varchar]
, #i [int]
, #Year [int]
, #CalcDay [int]
, #CalcMonth [int]
, #CalcYear [int]
, #ConcatDate [char] (10)
set #StartDate = '2012-12-30'
set #EndDate = '2013-01-28'
set #Year = 2013
set #i = -1
-- Going to do a while loop here and instead of Week number and Period Number I'm going to do some calculations
set #Week = (Select WeekNum from aaGreensPeriodListTest Where PeriodNum = 1 and WeekNum = 1)
set #Period = (Select PeriodNum from aaGreensPeriodListTest Where PeriodNum = 1 and WeekNum = 1)
set #CalcDate = #StartDate + #i
set #CalcMonth = datepart(mm,#calcdate)
insert into aaGreensPeriodTest(RealDate,GreensYear,GreensPeriod,GreensWeek)
values (#CalcDate,#Year,#Period,#Week)
select #CalcDate as CalcDate, #CalcMonth as CalcMonth
SQL Server 2005 does not support date type without time part.
If your need to get date as a string you can use convert function. For example:
declare #date datetime;
set #date = getdate();
select convert(varchar, #date, 101) -- that will return date in ‘mm/dd/yyyy’ format
If you need a datetime variable without time part for some calculations, you can use an expression below:
declare #date datetime;
set #date = getdate();
select dateadd(dd, datediff(dd, 0, #date), 0)
As per http://msdn.microsoft.com/en-ca/library/ms187928.aspx, you cannot cast float->date directly. It's simply not supporte. But you can cast a datetime->date, so you'll have to double-cast. Or given your example, triple-cast:
CAST(CAST(CAST(#CalcDate AS float) AS datetime) AS date)