Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在存储过程的单个参数中传递多个值?_Sql Server_Tsql_Sql Server 2005 - Fatal编程技术网

Sql server 如何在存储过程的单个参数中传递多个值?

Sql server 如何在存储过程的单个参数中传递多个值?,sql-server,tsql,sql-server-2005,Sql Server,Tsql,Sql Server 2005,我想在一个参数中传递多个值。SQL Server 2005只是一个建议。在SQLServer2005中,您无法真正做到这一点。至少没有直截了当的办法。您必须使用CSV、XML、Base64或JSON。但是,我强烈建议您不要这样做,因为它们都容易出错,并且会产生非常大的问题 如果能够切换到SQL Server 2008,则可以使用表值参数(,) 如果你不能,我建议你考虑在存储过程中执行它的必要性,也就是说,你真的想要(应该/必须)使用SP执行SQL动作。如果你正在解决一个问题,只要使用Ad hoc

我想在一个参数中传递多个值。SQL Server 2005只是一个建议。在SQLServer2005中,您无法真正做到这一点。至少没有直截了当的办法。您必须使用CSV、XML、Base64或JSON。但是,我强烈建议您不要这样做,因为它们都容易出错,并且会产生非常大的问题

如果能够切换到SQL Server 2008,则可以使用表值参数(,)

如果你不能,我建议你考虑在存储过程中执行它的必要性,也就是说,你真的想要(应该/必须)使用SP执行SQL动作。如果你正在解决一个问题,只要使用Ad hoc查询。如果出于教育目的想这样做,您可以尝试甚至不尝试上述内容。

您可以创建一个函数:

ALTER  FUNCTION [dbo].[CSVStringsToTable_fn] ( @array VARCHAR(8000) )
RETURNS @Table TABLE ( value VARCHAR(100) )
AS 
    BEGIN
        DECLARE @separator_position INTEGER,
            @array_value VARCHAR(8000)  

        SET @array = @array + ','

        WHILE PATINDEX('%,%', @array) <> 0 
            BEGIN
                SELECT  @separator_position = PATINDEX('%,%', @array)
                SELECT  @array_value = LEFT(@array, @separator_position - 1)

                INSERT  @Table
                VALUES  ( @array_value )

                SELECT  @array = STUFF(@array, 1, @separator_position, '')
            END
        RETURN
    END

当您尝试从SSR向PROC发送多值列表时,这非常有用


编辑:显示您可能需要强制转换-但是要小心控制CSV列表中发送的内容

您可以让存储过程获取一个
xml
类型化的输入变量,然后解压缩元素并获取它们。例如:

DECLARE @XMLData xml

DECLARE 
    @Code varchar(10),
    @Description varchar(10)

SET @XMLData = 
'
    <SomeCollection>
      <SomeItem>
        <Code>ABCD1234</Code>
        <Description>Widget</Description>
      </SomeItem>
    </SomeCollection>
'

SELECT 
    @Code = SomeItems.SomeItem.value('Code[1]', 'varchar(10)'),
    @Description = SomeItems.SomeItem.value('Description[1]', 'varchar(100)')
FROM @XMLDATA.nodes('//SomeItem') SomeItems (SomeItem)

SELECT @Code AS Code, @Description AS Description
结果:

Code        Description
==========  ===========
ABCD1234    Widget

您可以通过以下多种方式实现此目的:

  • 将字符串的CSV列表作为参数传递给(N)VARCHAR参数,然后在SP内对其进行解析

  • 首先创建一个XML字符串,然后将其作为XML数据类型参数传递。您需要在SP内解析XML,可能需要为此应用运算符

  • 在SP外部创建一个临时表,将多个值作为多行插入,此处不需要参数。然后在SP内部使用临时表

  • 如果您在2008年及以上,请尝试TVPs(表值参数)并将其作为参数传递


  • 单个参数可以有一个值。除非您将其设置为XML参数,并将多个值粘贴到XML中,然后将其解析回存储过程中的参数列表中…为什么,为什么,您会这样做?另一种方法是逗号分隔的值列表。。。但对于SQLServer2005来说,这并不是什么好方法。在SQLServer2008中,您可以使用表值参数。传入xml并没有什么问题。我个人写过大约50多个采用xml参数的过程。我们也使用xml参数,但它们很昂贵。为什么csv或xml不简单?它们比表值参数简单得多,在表值参数中,您必须为要传递的每种类型的参数定义一个自定义表类型。@BrianWhite我认为这对我们来说很简单,因为我们已经处理了这么久。如果你想一想,必须在CSV中传递值(你在一个点上构建,在另一个点上解包)是非常愚蠢的。如果你的值列是varchar(100),你将得到上面的隐式转换。我们有一个fn_splitInt,fn_splitBigInt,等等,就像上面一样,但是你把值设为一个int或一个bigint,当你插入它时,你把它转换成int。
    DECLARE @XMLData xml
    
    DECLARE 
        @Code varchar(10),
        @Description varchar(10)
    
    SET @XMLData = 
    '
        <SomeCollection>
          <SomeItem>
            <Code>ABCD1234</Code>
            <Description>Widget</Description>
          </SomeItem>
        </SomeCollection>
    '
    
    SELECT 
        @Code = SomeItems.SomeItem.value('Code[1]', 'varchar(10)'),
        @Description = SomeItems.SomeItem.value('Description[1]', 'varchar(100)')
    FROM @XMLDATA.nodes('//SomeItem') SomeItems (SomeItem)
    
    SELECT @Code AS Code, @Description AS Description
    
    Code        Description
    ==========  ===========
    ABCD1234    Widget