在存储过程中为同一变量传递多个值

时间:2013-12-31 23:11:19

标签: sql sql-server tsql

我有一个将多个值传递给存储过程的变量。

当我看到fidler时,我看到值正确传递,如

    arg1=331
    arg1=222
    arg1=876
    arg1=932

在我的存储过程中,我正在阅读

    procedure mainValues 
     @Arg1List     nvarchar(3000)
    as begin
  --Temp table to store split values
  declare @tmp_values table (
  value nvarchar(255) not null);   

   --function splitting values 
   insert into @tmp_values 
   select * from f_split(@Arg1List, ',');  

  --inserting in table value column is int.      
  insert into t_values (
   value
  )
  select 
  b.value
  from @tmp_values b;

当我测试它时,它不会在t_values表中添加任何值。我检查了功能等都工作正常。问题是@ Arg1List。看起来存储过程中没有值。请让我知道如何正确声明@ Arg1List,因此它需要多个值,因为它似乎是问题。

3 个答案:

答案 0 :(得分:2)

为了实现这一目标,您需要做一些事情,因为您的参数获得了创建表类型所需的多个值,并使您的商店过程接受该类型的参数。

分割函数很有用当你得到One String包含多个值但是当你传递多个值时,你需要做这样的事情....

表类型

CREATE TYPE dbo.TYPENAME AS TABLE 
 (
    arg int 
  )
 GO

接受该类型参数的存储过程

 CREATE PROCEDURE mainValues 
 @TableParam TYPENAME READONLY
 AS 
   BEGIN
    SET NOCOUNT ON;
  --Temp table to store split values
  declare @tmp_values table (
  value nvarchar(255) not null);   

   --function splitting values 
   INSERT INTO @tmp_values (value)
   SELECT arg FROM @TableParam


   SELECT * FROM @tmp_values  --<-- For testing purpose
END

EXECUTE PROC

声明该类型的变量并使用您的值填充它。

 DECLARE @Table TYPENAME     --<-- Variable of this TYPE

 INSERT INTO @Table                --<-- Populating the variable 
 VALUES (331),(222),(876),(932)

EXECUTE mainValues @Table   --<-- Stored Procedure Executed 

<强>结果

╔═══════╗
║ value ║
╠═══════╣
║   331 ║
║   222 ║
║   876 ║
║   932 ║
╚═══════╝

答案 1 :(得分:1)

您的存储过程旨在接受单个参数Arg1List。您不能将4个参数传递给只接受一个参数的过程。

要使其工作,调用过程的代码需要将您的参数连接成一个不超过3000个字符的字符串,并将其作为单个参数传递。

答案 2 :(得分:0)

好吧,如果没有对你的确切设置的更大看法,如何调用它以及f_split中发生了什么,我可能很难调试这种情况,因为我基本上只是在猜测。但是,我可以提供一种不涉及UDF的替代解决方案,而是依赖于SQL Server的机制构建...... XML。

下面的proc声明接受一个名为@parmsXML的XML类型参数。这将替换您的@ Arg1List参数。当您执行dbo.mainValues时,您将@parmsXML参数作为XML节点的字符串而不是以逗号分隔的列表提供(我假设这是您正在执行的操作,但从您的问题来看,它并不完全清楚):

<parms>
    <parm>331</parm>
    <parm>222</parm>
    <parm>876</parm>
    <parm>932</parm>
</parms>

存储过程执行此操作:

  1. 只需直接从@parmsXML变量中选择值
  2. 将@parmsXML变量中的值选择为temp #t_values表
  3. #t_values表中的SELECT
  4. 在您自己的实现中,您可以摆脱第一步(Just select ....),然后将SELECT INTO更改为INSERT INTO SELECT。

    我有以下脚本设置,以便它将DROP IF EXISTS然后创建proc,然后使用@parmsXML设置执行它,如上所述。

    --========================================================================================================================
    /* DROP AND RECREATE PROC                                                                                               */
    --========================================================================================================================
    
    IF EXISTS (
      SELECT * 
        FROM INFORMATION_SCHEMA.ROUTINES 
       WHERE SPECIFIC_SCHEMA = N'dbo'
         AND SPECIFIC_NAME = N'mainValues' 
    )
       DROP PROCEDURE dbo.mainValues
    GO
    
    CREATE PROCEDURE dbo.mainValues
        @parmsXML XML
    AS
    
    --========================================================================================================================
    /* INTERPRETER DIRECTIVES                                                                                               */
    --========================================================================================================================
    
    SET NOCOUNT ON;    -- Turn off "(N row(s) affected)" messages
    SET XACT_ABORT ON; -- Auto ROLLBACK on exception
    
    --========================================================================================================================
    /* PARMS PROCESSING                                                                                                     */
    --========================================================================================================================
    
    -- select from @parmsXML
    
    RAISERROR('Selecting values directly from @parmsXML', 0, 1);
    
    SELECT Parm = n.x.value('.[1]', 'INT')
    FROM @parmsXML.nodes('/parms[1]/parm') n(x)
    ;
    
    -- insert into
    
    RAISERROR('Inserting @parmsXML values into #t_values', 0, 1);
    
    SELECT Parm = n.x.value('.[1]', 'INT')
    INTO #t_values
    FROM @parmsXML.nodes('/parms[1]/parm') n(x)
    ;
    
    -- select from #t_values
    
    RAISERROR('Selecting from #t_values', 0, 1);
    
    SELECT * 
    FROM #t_values
    ;
    
    
    GO
    
    --========================================================================================================================
    /* Example EXEC code runs stored proc with @parmsXML supplied                                                           */
    --========================================================================================================================
    
    EXECUTE dbo.mainValues @parmsXML = '
        <parms>
            <parm>331</parm>
            <parm>222</parm>
            <parm>876</parm>
            <parm>932</parm>
        </parms>
        '
    GO