传递多个值以获取CSV输出

时间:2013-04-05 10:07:47

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2

Create procedure temp
(
@MID smallint
)
as
Begin

select TranID,
[MonthValue]=(CASE WHEN @MID=1 THEN Jan
    WHEN @MID=2 THEN Feb
    WHEN @MID=3 THEN Mar
    WHEN @MID=4 THEN Apr
    WHEN @MID=5 THEN May
    WHEN @MID=6 THEN Jun
    WHEN @MID=7 THEN Jul
    END)
    FROM 
    TblTran as M
 where TranID=1 and
       M.Month = @MID
end

这是一个带参数@MID的存储过程 我正在使用SSRS生成报告 如果将单个值传递给参数,则可以正常工作。

例如 -

交易表

TranID | Apr |  May  | Jun   | Jul  

1     |  50  |   30  |  11   |   30   
2     |  51  |   39  |  100  |   30

如果我用
执行 Exec 4
结果是我所期待的

TranID  |  MonthValue    

1       |   50   **-- ie Aprils value**

但是我需要将多个值传递给参数
喜欢

exec 4,5,6

并且期望的结果应该是

TranID  |  MonthValue        

1       |   50,30,11     ***-->Comma Separated values of columns  

我怎样才能实现这样的结果?

3 个答案:

答案 0 :(得分:0)

存储过程必须具有有限数量的预定义参数,此外,您尝试实现的内容不保证存储过程。 更好的解决方案是将值存储在表create table (mid smallint, monthtext varchar(20))中并查找您需要的内容。

从它的外观中注意,您还可以使用日期时间功能返回1-12个月的编号。

DECLARE @Mth smallint SET @Mth = 11 SELECT DateName(mm,DATEADD(mm,@Mth,-1)) as [MonthName]

答案 1 :(得分:0)

您可以在定义中定义多个值,默认值为null,这样您只需传入所需的项目数。

create procedure fred
(
  @i1 int = null,
  @i2 int = null,
  @i3 int = null,
...

然后检查值是否为空。

我同意使用系统功能可能是一个更好的解决方案。

答案 2 :(得分:0)

您可以使用分割功能,例如

CREATE FUNCTION dbo.SplitInts
(
    @List       VARCHAR(MAX),
    @Delimiter  VARCHAR(32)
)
RETURNS TABLE
AS
    RETURN 
    (
      SELECT Item = CONVERT(INT, Item) 
        FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number, 
          CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)))
        FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
          FROM sys.all_objects) AS n(Number)
        WHERE Number <= CONVERT(INT, LEN(@List))
        AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
      ) AS y
    );

然后将参数作为单字符串传递而不是单独的参数(you can do this easily with SSRS according to this post):

EXEC dbo.procedurename @param = '4,5,6';

这是一个使用声明的变量和动态SQL来获取所需输出的快速示例:

CREATE TABLE dbo.TransactionsTest
(TranID INT PRIMARY KEY, Apr INT, May INT, Jun INT, Jul INT);

INSERT dbo.TransactionsTest VALUES
(1,50,30,11 ,30),   
(2,51,39,100,30);


DECLARE @months VARCHAR(32) = '4,5,6';



DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql = 'SELECT TranID,MonthValue=' + STUFF(
(SELECT '+'',''+RTRIM(' 
  + CONVERT(CHAR(3),DATENAME(MONTH, DATEADD(MONTH, Item-1, 0))) + ')' 
  FROM dbo.SplitInts(@months,',') 
  ORDER BY Item
  FOR XML PATH, TYPE).value('.[1]', 'nvarchar(max)'),1,5,'') + '
   FROM dbo.TransactionsTest ORDER BY TranID;';

PRINT @sql;

EXEC sp_executesql @sql;

结果:

-- printed in messages pane:

SELECT TranID,MonthValue=RTRIM(Apr)+','+RTRIM(May)+','+RTRIM(Jun) 
    FROM dbo.TransactionsTest ORDER BY TranID;

-- grid/text results:

TranID  MonthValue
------  ----------
1       50,30,11
2       51,39,100

SQLfiddle demo