SQL - 带有多个参数的参数化过程,如数组

时间:2016-06-09 09:18:00

标签: sql sql-server tsql

我的程序非常简单:

CREATE PROCEDURE [Report]
@statusValue varchar(200) = '%'
AS
BEGIN
SELECT * FROM SomeTable
WHERE Something LIKE UPPER(@statusValue)
END

我想提供用户设置的多个statusValue。因为我的表中有6个级别的statusValue,所以我想提供用户将所需的statusValue定义为过程参数 - 类似于数组。

我不知道,它究竟是如何运作的 - 我在这方面很新 - 但我想假设有这样的程序:

EXEC Report @statusValue = 'statusValue1|statusValue2|statusValue3'

你碰巧知道,我怎样才能调整我的程序以获得所需的输出。非常感谢提前。

3 个答案:

答案 0 :(得分:0)

实现此目的的最简单方法之一是使用自定义类型。示例摘录如下:

CREATE TYPE dbo.StatusList
AS TABLE
(
  statusValue varchar(200)
);
GO

CREATE PROCEDURE [Report]
@statusValue AS dbo.StatusList READONLY
AS
BEGIN
   SELECT * FROM SomeTable
   WHERE Something IN (SELECT * FROM @statusValue)
END
GO

- EDIT ---

如果您使用的是SSMS,则可以执行以下步骤:

DECLARE @status dbo.StatusList
INSERT INTO @status VALUES('Pending')

EXEC [Report] @status

答案 1 :(得分:0)

在这种情况下,您需要拆分功能。因为没有办法处理你需要的东西。另一种添加许多变量的方法。但在你的情况下,创建分割函数并使用它来解析你的字符串就足够了。请在下面找到拆分功能:

CREATE FUNCTION [dbo].[ufnSplitInlineStringToParameters] (
    @list NVARCHAR(MAX)
    ,@delim NCHAR(1) = ','
    )
RETURNS TABLE
AS
RETURN
WITH csvTbl(START, STOP) AS (
        SELECT START = CONVERT(BIGINT, 1)
            ,STOP = CHARINDEX(@delim, @list + CONVERT(NVARCHAR(MAX), @delim))

        UNION ALL

        SELECT START = STOP + 1
            ,STOP = CHARINDEX(@delim, @list + CONVERT(NVARCHAR(MAX), @delim), STOP + 1)
        FROM csvTbl
        WHERE STOP > 0
        )

SELECT LTRIM(RTRIM(CONVERT(NVARCHAR(4000), SUBSTRING(@list, START, CASE 
                        WHEN STOP > 0
                            THEN STOP - START
                        ELSE 0
                        END)))) AS VALUE
FROM csvTbl
WHERE STOP > 0

GO

答案 2 :(得分:0)

使用以下用户定义函数从分隔字符串(例如管道)返回值:

CREATE FUNCTION [dbo].[stringlist_to_table]
    (@list      varchar(8000),
    @delimiter nchar(1) = N',') 
RETURNS @tbl TABLE (value varchar(8000)) AS
BEGIN
    DECLARE @pos      int,
        @tmpstr   varchar(8000),
        @tmpval   varchar(8000);

    SET @tmpstr = @list;
    SET @pos = charindex(@delimiter , @tmpstr);

    WHILE @pos > 0
    BEGIN
        SET @tmpval = ltrim(rtrim(left(@tmpstr, @pos - 1)))
        INSERT @tbl (value) VALUES(@tmpval)
        SET @tmpstr = substring(@tmpstr, @pos + 1, len(@tmpstr))
        SET @pos = charindex(@delimiter, @tmpstr)
    END

    INSERT @tbl(value) VALUES (ltrim(rtrim(@tmpstr)));
    RETURN
END

现在使用以下过程获取所需的输出:

CREATE PROCEDURE [Report]
    @statusValue varchar(200) = '%'
AS
BEGIN

    DECLARE @iterator INT = 1;
    DECLARE @total INT = 1;
    DECLARE @keyword VARCHAR(100) = '';

    SELECT ROW_NUMBER() OVER (ORDER BY value) SNo, value keyword
    INTO #temp
    FROM dbo.stringlist_to_table(@statusValue, '|')

    SELECT * 
    INTO #output
    FROM SomeTable
    WHERE 1 = 0;

    SELECT @total = MAX(SNo), @iterator = MIN(Sno)
    FROM #temp

    WHILE (@iterator <= @total)
    BEGIN
        SELECT @keyword = '%' + keyword + '%'
        FROM #temp
        WHERE SNo = @iterator;

        INSERT INTO #output
        SELECT * 
        FROM SomeTable
        WHERE Something LIKE @keyword

        SET @iterator = @iterator + 1;
    END

    SELECT *
    FROM #output;

    DROP TABLE #output, #temp;
END