通过将值数组传递给存储过程参数来获取记录的正确方法是什么?

时间:2016-12-27 14:01:50

标签: sql-server stored-procedures

我有以下表格:

expense_bugdet_head_master

Expense_Budget_ID   Transaction_ID  Transaction_Date        Department_ID   Branch_ID   Project_ID  Start_Date                  End_Date                Description
1                   EBF151600001    2015-11-07 00:00:00.000 NULL            NULL        GENERAL     2015-01-01  00:00:00.000    2015-12-31 00:00:00.000 Personal Computer
2                   EBF151600002    2015-11-07 00:00:00.000 NULL            NULL        GENERAL     2015-01-01  00:00:00.000    2015-12-31 00:00:00.000 UPS
3                   EBF151600003    2015-11-07 00:00:00.000 NULL            NULL        GENERAL     2015-01-01  00:00:00.000    2015-12-31 00:00:00.000 AC
4                   EBF151600004    2015-11-07 00:00:00.000 NULL            NULL        GENERAL     2015-01-01  00:00:00.000    2015-12-31 00:00:00.000 Laptop
5                   EBF151600005    2015-11-07 00:00:00.000 NULL            NULL        GENERAL     2015-01-01  00:00:00.000    2015-12-31 00:00:00.000 Generator

expense_bugdet_head_detail

Expense_Budget_Detail_ID    Expense_Budget_ID   Expense_Budget_Type_ID  Amount      Description         SL_Code Last_Modified_By    last_Modified_Date
1                           1                   NULL                    91310.00    Personal Computer   795031  NULL                NULL
2                           2                   NULL                    98810.00    UPS                 795031  NULL                NULL
3                           3                   NULL                    642344.00   AC                  795031  NULL                NULL
4                           4                   NULL                    1364000.00  Laptop              795031  NULL                NULL
5                           5                   NULL                    2377372.00  Generator           795031  NULL                NULL

这是我最近创建的存储过程:

-- demo 'UPS,AC'
ALTER PROCEDURE demo
    @Budget_Description varchar(500) = NULL
AS
BEGIN
    DECLARE @arr_str VARCHAR(max)
    DECLARE @Temp_table Table (column1 VARCHAR(100))

    IF @Budget_Description <> ''
    BEGIN
        SET @arr_str = @Budget_Description

        WHILE LEN(@arr_str) > 0
        BEGIN
            DECLARE @Description VARCHAR(100)

            IF CHARINDEX(',', @arr_str) > 0
                SET @Description = SUBSTRING(@arr_str, 0, CHARINDEX(',', @arr_str))
            ELSE
            BEGIN
                SET  @Description = @arr_str
                SET @arr_str = ''
            END

            INSERT INTO  @Temp_table VALUES (@Description)

            SET @arr_str = REPLACE(@arr_str, @Description + ',', '')
        END
    END

    SELECT
        EBM.Transaction_ID,
        EBM.Transaction_Date,
        EBM.Start_Date,
        EBM.End_Date,
        EBD.Description,
        EBD.Amount,
        EBD.SL_Code
    FROM
        dbo.EXPENSE_BUDGET_MASTER EBM
    INNER JOIN
        EXPENSE_BUDGET_DETAIL EBD ON EBD.Expense_Budget_ID = EBM.Expense_Budget_ID 
    WHERE
        EBD.Description IN (ISNULL((SELECT column1 FROM @Temp_table), EBD.Description))
END

现在,我正在尝试的是在将值数组传递给存储过程参数时获取记录。如果我将单个值传递给存储过程参数,我会得到一条记录。但是,如果我传递多个值,我会得到以下错误。请帮帮我。

  

子查询返回的值超过1。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。

3 个答案:

答案 0 :(得分:1)

可能是此行中的语法错误

Where
            EBD.Description  in (ISNULL((select column1 from @Temp_table),EBD.Description))

将此行更改为

Where


       EBD.Description  in (select ISNULL(column1,EBD.Description) from @Temp_table)

更新答案

-- demo 'UPS,AC'
ALTER PROCEDURE demo
    @Budget_Description varchar(500) = NULL
AS
BEGIN
    DECLARE @arr_str VARCHAR(max)
    DECLARE @Temp_table Table (column1 VARCHAR(100))

    IF @Budget_Description <> ''
    BEGIN
        SET @arr_str = @Budget_Description

        WHILE LEN(@arr_str) > 0
        BEGIN
            DECLARE @Description VARCHAR(100)

            IF CHARINDEX(',', @arr_str) > 0
                SET @Description = SUBSTRING(@arr_str, 0, CHARINDEX(',', @arr_str))
            ELSE
            BEGIN
                SET  @Description = @arr_str
                SET @arr_str = ''
            END

            INSERT INTO  @Temp_table VALUES (@Description)

            SET @arr_str = REPLACE(@arr_str, @Description + ',', '')
        END

         SELECT
        EBM.Transaction_ID,
        EBM.Transaction_Date,
        EBM.Start_Date,
        EBM.End_Date,
        EBD.Description,
        EBD.Amount,
        EBD.SL_Code
    FROM
        dbo.EXPENSE_BUDGET_MASTER EBM
    INNER JOIN
        EXPENSE_BUDGET_DETAIL EBD ON EBD.Expense_Budget_ID = EBM.Expense_Budget_ID 
    WHERE
        EBD.Description  IN (select ISNULL(column1,EBD.Description) from @Temp_table)

   END

   IF @Budget_Description IS NULL or IF NOT EXISTS(SELECT Description FROM @Temp_Table WHERE Description IN (SELECT Description FROM EXPENSE_BUDGET_DETAIL ))
   BEGIN

    SELECT
        EBM.Transaction_ID,
        EBM.Transaction_Date,
        EBM.Start_Date,
        EBM.End_Date,
        EBD.Description,
        EBD.Amount,
        EBD.SL_Code
    FROM
        dbo.EXPENSE_BUDGET_MASTER EBM
    INNER JOIN
        EXPENSE_BUDGET_DETAIL EBD ON EBD.Expense_Budget_ID = EBM.Expense_Budget_ID 

   END

END

答案 1 :(得分:1)

我想你已经接受了上面的答案。但你也可以这样做:

1你可以声明变量:

DECLARE @TempCount bigint 

现在,在您的代码中将while循环放在下面:

if exists (select * from @Temp_table)
        begin 
         set @TempCount = 1
        end
    else
        begin 
         set @TempCount = 0
end

现在更新你的where子句:

AND (
        (@TempCount = 1 AND EBD.Description IN (select column1 from @Temp_table) )
        OR (@TempCount = 0 AND EBD.Description = EBD.Description )
    )

现在,您可以在不使用接受的答案中提到的任何多项选择查询的情况下获得您的愿望结果。

答案 2 :(得分:0)

也许您应该考虑sp的表值参数。检查一下 https://msdn.microsoft.com/en-us/library/bb510489.aspx