将同一列的多个参数传递给SQL Server选择SP

时间:2009-06-01 14:31:49

标签: asp.net sql sql-server sql-server-2005

我在web.config中有一个字符串值 - 例如2个由","分隔的guid。我需要动态查询数据库(即我不知道web.config中的逗号可以分隔多少个值)并在表上运行一个select语句,传递这些值并得到所有相关的例如:

select * from tablename where columnname = string1 string2 string3 etc etc

某些字符串可能只包含1个guid,有些可能包含10个

4 个答案:

答案 0 :(得分:4)

查看Erland Sommarskogs关于这个主题的优秀文章:

http://www.sommarskog.se/arrays-in-sql-2005.html

除了将多个值传递给过程之外,SQL Server 2008还提供table-valued parameters

马克

答案 1 :(得分:1)

你想要一个“IN”状态。如果您确实信任您的web.config并且可以要求配置的元素也包含在引号中,您可以直接将其放入sql语句中:

select * from tablename where columnname IN ( "web.config value here" )

但请注意,像这样的动态sql 非常很危险。另一方面,安全地传递它们可以是tricky

答案 2 :(得分:1)

这是基于Erland Sommarskogs的文章:

http://www.sommarskog.se/arrays-in-sql-2005.html

在使用我的功能之前,您需要设置一个“帮助程序”表,每个数据库只需执行一次这样的操作:

CREATE TABLE Numbers
(Number int  NOT NULL,
    CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
DECLARE @x int
SET @x=0
WHILE @x<8000
BEGIN
    SET @x=@x+1
    INSERT INTO Numbers VALUES (@x)
END

使用此函数来分割您的字符串,该字符串不会循环且非常快:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn              char(1)              --REQUIRED, the character to split the @List string on
    ,@List                 varchar(8000)        --REQUIRED, the list to split apart
)
RETURNS
@ParsedList table
(
    ListValue varchar(500)
)
AS
BEGIN

/**
Takes the given @List string and splits it apart based on the given @SplitOn character.
A table is returned, one row per split item, with a column name "ListValue".
This function workes for fixed or variable lenght items.
Empty and null items will not be included in the results set.


Returns a table, one row per item in the list, with a column name "ListValue"

EXAMPLE:
----------
SELECT * FROM dbo.FN_ListToTable(',','1,12,123,1234,54321,6,A,*,|||,,,,B')

    returns:
        ListValue  
        -----------
        1
        12
        123
        1234
        54321
        6
        A
        *
        |||
        B

        (10 row(s) affected)

**/



----------------
--SINGLE QUERY-- --this will not return empty rows
----------------
INSERT INTO @ParsedList
        (ListValue)
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''



RETURN

END --Function FN_ListToTable

您可以将此函数用作连接中的表,这将快速并使用索引:

SELECT
    Col1, COl2, Col3...
    FROM  YourTable
        INNER JOIN FN_ListToTable(',',@YourString) s ON  YourTable.ID = s.ListValue

你可以拆分字符串或数字,这里有一些字符串示例:

DECLARE @YourString varchar(8000)
SET @YourString='monkey,elephant,dog,bear,zebra'
select * from FN_ListToTable(',',@YourString)

SET @YourString='two words,three words here,four words right here,five is the magic number,six words is even more fun'
select * from FN_ListToTable(',',@YourString)


SET @YourString='Doe, Jane; Smith, Joe; Public, John Q.'
select * from FN_ListToTable(';',@YourString)

答案 3 :(得分:0)

您不必发送多个参数,只需一个字符串

一种可能性是将该字符串解析为SQL存储过程并构建动态查询

另一个可能性是在每个插入''字符,并使用下面的代码

'aaa','bbb','ccc'

myTable
------------
ID  Name

1   eee
2   aaa
3   ggg
4   hhh
5   bbb


declare @stmt nvarchar(1000)
set @stmt = 'select * from myTable where Name in (''aaa'',''bbb'',''ccc'')'
exec spexecute_sql @stmt