我正在处理SSRS报告并使用允许您选择多个选项的参数。但是,当我这样做时,我收到一个错误,指出:
将数据类型nVarChar转换为Int。
时出错数据库中的数据是Integer。该参数设置为整数,只选择一个选项时效果很好。当我选择多个选项时会出现问题。
我的同事想出了一个解决办法,但如果可能的话,我想要一些更优雅,更容易插入的东西。
这是他的解决方法:
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 )
毋庸置疑,我相信有更好的方法可以实现这一目标。如果有人有任何想法,请告诉我。
以下是我正在使用的完整查询。但它没有选择任何内容,因此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
答案 0 :(得分:0)
在SQL Server 2008之前,按一个或多个值过滤的标准方法是将XML文档传递给存储过程并加入它。在这种情况下,您可以将数据作为字符串传递,其中整数用逗号分隔,然后将其转换为XML文档,然后加入XML。因此,您应该将SSRS中的多选项更改为文本数据类型。这是一篇文章,向您展示如何打开XML文档:http://blog.sqlauthority.com/2009/02/13/sql-server-simple-example-of-reading-xml-file-using-t-sql/
SQL Server 2008允许您使用表值参数,但同样,最好将数据作为逗号分隔的整数字符串传递,然后让存储过程将数据放入表值参数中,然后加入那个。这是一篇介绍如何使用表值参数的帖子:http://blog.sqlauthority.com/2008/08/31/sql-server-table-valued-parameters-in-sql-server-2008/