[英]Issue with input parameters and data types in SQL Server
I have a table called report
with 3 columns: 我有一个名为
report
的表,其中包含3列:
reportdate date, name varchar(10), location varchar(10)
Sample data: 样本数据:
reportdate name location
-------------------------------
2014-01-01 sachin vizag
2014-02-02 tendulkar vizag
2014-03-03 ram vizag
2014-04-04 robert vizag
2014-05-05 rahim vizag
2014-06-06 king vizag
2013-01-01 sachin vizag
2013-02-02 tendulkar vizag
2013-03-03 ram vizag
2013-04-04 robert vizag
2013-05-05 rahim vizag
2013-06-06 king vizag
My actual requirement was to create a date parameter for SSRS reports. 我的实际要求是为SSRS报告创建日期参数。 So I have taken
reportdate
column for that purpose. 因此,我为此选择了
reportdate
列。
I need to create 3 parameters from single reportdate
column 我需要从单个
reportdate
列创建3个参数
Parameter 1 : 参数1:
I need to select only year value from reportdate
column, for which I used this query 我只需要从
reportdate
列中选择年份值,为此我使用了该查询
select distinct YEAR(ReportDate) as ReportYear
from report
and the result of it was 结果是
ReportYear
----------
2013
2014
Parameter 2: 参数2:
I need to create a parameter for months column and this is the stored procedure which I have created 我需要为months列创建一个参数,这是我创建的存储过程
create procedure months
@years date
as begin
select distinct
Case
When CONVERT(varchar(2), ReportDate, 101) = 01 Then 'JAN'
When CONVERT(varchar(2), ReportDate, 101) = 02 Then 'FEB'
When CONVERT(varchar(2), ReportDate, 101) = 03 Then 'MAR'
When CONVERT(varchar(2), ReportDate, 101) = 04 Then 'APR'
When CONVERT(varchar(2), ReportDate, 101) = 05 Then 'MAY'
When CONVERT(varchar(2), ReportDate, 101) = 06 Then 'JUN'
When CONVERT(varchar(2), ReportDate, 101) = 07 Then 'JUL'
When CONVERT(varchar(2), ReportDate, 101) = 08 Then 'AUG'
When CONVERT(varchar(2), ReportDate, 101) = 09 Then 'SEP'
When CONVERT(varchar(2), ReportDate, 101) = 10 Then 'OCT'
When CONVERT(varchar(2), ReportDate, 101) = 11 Then 'NOV'
When CONVERT(varchar(2), ReportDate, 101) = 12 Then 'DEC'
end ReportMonth
--,year(reportdate) As ReportYear
from
report
where
reportdate in (select CAST(cast(@years as datetime)as date))
--order by DATEPART(m,ReportMonth)
end
I am passing years as parameter in the above procedure, if I pass value 2013/2014
as parameter then my output has to be as below 我在上述过程中将年份作为参数传递,如果我将值
2013/2014
作为参数传递,则我的输出必须如下
ReportMonth ReportYear
-----------------------
JAN 2014
FEB 2014
MAR 2014
APR 2014
MAY 2014
JUN 2014
JAN 2013
FEB 2013
MAR 2013
APR 2013
MAY 2013
JUN 2013
instead of the above output I am getting below output if I run the above stored procedure for year 2013. 如果我运行2013年以上的存储过程,我将得到低于输出的结果。
ReportMonth ReportYear
------------------------
JAN 2013
I don't understand why only one month is being populated instead of all the available months in the table. 我不明白为什么只填写一个月而不是表格中所有可用的月份。
I would say your where clause doesn't look correct. 我会说你的where子句看起来不正确。 You should be checking the DATEPART (YEAR,reportdate) to equal the year you passed as a parameter to your stored procedure.
你应该检查DATEPART (YEAR,reportdate),你作为一个参数传递的一年等于你的存储过程。
Your WHERE clause checks if reportdate is IN a set with only one date, which equals the 1 january of that year. 您的WHERE子句检查reportdate是否在只有一个日期(等于该年1月1日)的集合中。 This is obviously not what you want.
这显然不是您想要的。
If you want to pass parameters as for example 2013/2014
you probably need to use a function to split the parameters (there are plenty of examples of split functions around the net), but if you don't want to handle splitting parameters one way to accomplish this is to use dynamic sql in the procedure: 如果要传递参数,例如
2013/2014
,则可能需要使用函数来拆分参数(网上有很多拆分函数的示例),但是如果您不想以一种方式处理拆分参数要做到这一点,就是在过程中使用动态SQL:
CREATE PROC Months @YEARS VARCHAR(50)
AS
BEGIN
DECLARE @SQL VARCHAR(500) =
'SELECT DISTINCT
MONTH(ReportDate) AS [Month],
UPPER(LEFT(DATENAME(MONTH,ReportDate),3)) AS ReportMonth,
YEAR(ReportDate) AS ReportYear
FROM Report
WHERE YEAR(ReportDate) IN (' + @YEARS + ')
ORDER BY ReportYear DESC, [Month]'
EXEC (@SQL)
END;
I included the month number for sorting (and it might be good to have too). 我包括了用于排序的月份号(也可能会很好)。
When called as EXEC Months '2013, 2014'
this would output: 当称为
EXEC Months '2013, 2014'
将输出:
Month ReportMonth ReportYear
----------- ----------- -----------
1 JAN 2014
2 FEB 2014
3 MAR 2014
4 APR 2014
5 MAY 2014
6 JUN 2014
1 JAN 2013
2 FEB 2013
3 MAR 2013
4 APR 2013
5 MAY 2013
6 JUN 2013
Another option would be to create a table valued type, declare a variable based on that type, insert the years you want to filter by and have the procedure accept a table valued type as parameter: 另一个选择是创建一个表值类型,基于该类型声明一个变量,插入要过滤的年份,并让过程接受表值类型作为参数:
CREATE TYPE YearsType AS TABLE (Y INT)
GO
CREATE PROC M @YEARS YearsType READONLY
AS
SELECT DISTINCT
MONTH(ReportDate) AS [Month],
UPPER(LEFT(DATENAME(MONTH,ReportDate),3)) AS ReportMonth,
YEAR(ReportDate) AS ReportYear
FROM Report
WHERE YEAR(ReportDate) IN (SELECT Y FROM @YEARS)
ORDER BY ReportYear DESC, [Month]
GO
DECLARE @Years YearsType
--INSERT @Years VALUES (2013)
INSERT @Years VALUES (2013),(2014)
EXECUTE M @YEARS
This obviously has some drawbacks in that you need to declare a local table variable and populate it before calling the procedure. 这显然具有一些缺点,因为您需要在调用过程之前声明一个本地表变量并填充它。
Sample SQL Fiddle for both versions above. 上面两个版本的示例SQL Fiddle 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.