简体   繁体   English

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

[英]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    

Sample SQL Fiddle 示例SQL提琴

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM