SQL Server中输入参数和数据类型的问题

时间:2014-09-15 08:24:08

标签: sql sql-server

我有一个名为report的表格,其中包含3列:

reportdate date, name varchar(10), location varchar(10) 

示例数据:

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    

Sample SQL Fiddle

我的实际要求是为SSRS报告创建日期参数。所以我为此目的采用了reportdate专栏。

我需要从单个reportdate

创建3个参数

参数1:

我只需从reportdate列中选择年份值,我使用此查询

select distinct YEAR(ReportDate) as ReportYear 
from report  

,结果是

ReportYear
----------
2013
2014

参数2:

我需要为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   

我在上面的过程中作为参数传递了几年,如果我将值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  

而不是上面的输出,如果我运行2013年的上述存储过程,我将低于输出。

ReportMonth ReportYear
------------------------
JAN 2013  

我不明白为什么只填写一个月而不是表中的所有可用月份。

2 个答案:

答案 0 :(得分:1)

我会说你的where子句看起来不正确。您应该检查DATEPART(年份,报告日期),以等于您作为存储过程参数传递的年份。

您的WHERE子句检查reportdate是否为只有一个日期的集合,该日期等于该年的1月1日。这显然不是你想要的。

答案 1 :(得分:1)

如果你想传递参数{例如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;

我包含了用于排序的月份编号(也可能是好的)。

当调用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

另一种选择是创建一个表值类型,根据该类型声明一个变量,插入要过滤的年份,让过程接受一个表值类型作为参数:

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 

这显然有一些缺点,你需要在调用过程之前声明一个本地表变量并填充它。

上述两个版本的

Sample SQL Fiddle