我的报告中有一个名为@Animal的多值参数,其中包含(' Cat',' Dog',' Mouse')。
内部数据集我需要获得“Cat',Dog'”,#39;鼠标'并将其存储到@AnimalName表变量中。
"硬编码"方式是:
DECLARE @AnimalName TABLE (Name nvarchar (10))
INSERT INTO @AnimalName SELECT ('Cat');
INSERT INTO @AnimalName SELECT ('Dog');
INSERT INTO @AnimalName SELECT ('Mouse');
我知道我可以直接在我的数据集中使用@Animal,我之所以这样做是因为我试图提高报告的性能。许多多值参数将使报告永远运行。
有没有人知道如何(语法)获取@Animal数据值并将其存储到数据集内的表变量@AnimalName中?
谢谢堆!
答案 0 :(得分:1)
将逗号分隔的字符串传递给存储过程,并在存储过程中使用表值函数将多值参数转换为表格。
CREATE PROC GetAllAnimals
@AnimalList nvarchar(max)
AS
DECLARE @Animals TABLE (Animal nvarchar(10))
INSERT INTO @Animals SELECT * FROM dbo.fnGetValueListFromMultiSelect(@AnimalList)
然后使用@Animals表在查询中进行内连接
下面声明的函数。
对于整数(或ID)值
CREATE FUNCTION [dbo].[fnGetIdListFromMultiSelect](@String nvarchar(MAX))
RETURNS @Results TABLE ([Id] int)
AS
BEGIN
DECLARE @Delimiter CHAR(1)
DECLARE @INDEX INT
DECLARE @SLICE nvarchar(4000)
IF @String IS NULL RETURN
SET @Delimiter = ','
SET @INDEX = 1
WHILE @INDEX !=0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF @INDEX !=0
BEGIN
SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
END
ELSE
SELECT @SLICE = @STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO @Results([Id]) VALUES(CAST(@SLICE AS INT))
-- BREAK OUT IF WE ARE DONE
IF LEN(@STRING) = 0 BREAK
END
RETURN
END
对于字符串值
CREATE FUNCTION [dbo].[fnGetValueListFromMultiSelect](@String nvarchar(MAX))
RETURNS @Results TABLE ([Item] nvarchar(128) Primary Key)
AS
BEGIN
DECLARE @Delimiter CHAR(1)
DECLARE @INDEX INT
DECLARE @SLICE nvarchar(4000)
SET @Delimiter = ','
SET @INDEX = 1
WHILE @INDEX !=0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF @INDEX !=0
BEGIN
SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
END
ELSE
SELECT @SLICE = @STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO @Results([Item]) VALUES(@SLICE)
-- BREAK OUT IF WE ARE DONE
IF LEN(@STRING) = 0 BREAK
END
RETURN
END