查询有效但在将其放入存储过程时不起作用

时间:2013-02-24 15:12:44

标签: c# sql-server tsql stored-procedures

我测试以下查询并正常工作

select * from tbl where userName in ('A','B','C')

但是当我创建存储过程并将参数传递给它时不起作用(参数是正确的)

SqlCommand sc = new SqlCommand("exec example @userName",...
sc.Parameters.AddWithValue("@userName", "'A','B','C'");
...

// Stored Procedure
create procedure example 
    @users varchar(100)
as
    select * from tbl where userName in ('@users')

2 个答案:

答案 0 :(得分:2)

不要将参数放在引号中。

然而,只有:

select * from tbl where userName in (@users)

当你试图在恰好代表元素列表的字符串上使用in函数时,它将无法正常工作。

您需要将字符串转换为数组,然后在select语句中使用它:

MSDN有example function for doing this

CREATE FUNCTION dbo.Split 
   (  @Delimiter varchar(5), 
      @List      varchar(8000)
   ) 
   RETURNS @TableOfValues table 
      (  RowID   smallint IDENTITY(1,1), 
         [Value] varchar(50) 
      ) 
AS 
   BEGIN
      DECLARE @LenString int 

      WHILE len( @List ) > 0 
         BEGIN 
            SELECT @LenString = 
               (CASE charindex( @Delimiter, @List ) 
                   WHEN 0 THEN len( @List ) 
                   ELSE ( charindex( @Delimiter, @List ) -1 )
                END
               ) 

            INSERT INTO @TableOfValues 
               SELECT substring( @List, 1, @LenString )

            SELECT @List = 
               (CASE ( len( @List ) - @LenString ) 
                   WHEN 0 THEN '' 
                   ELSE right( @List, len( @List ) - @LenString - 1 ) 
                END
               ) 
         END
      RETURN 
    END 

然后像这样使用它:

select * from tbl where userName in (SELECT * FROM dbo.Split( ',', @users ))

答案 1 :(得分:1)

“in”查询众所周知难以参数化。首先,不要将参数放在引号中 - 那么它不是参数:它是一个字符文字。但是:你也不能只是使用一个参数 - 因为这会搜索一个只有引号和逗号的单个值 - 而不是你想要的。

这里有各种方法;例如,在服务器上使用“拆分”功能,并在内部连接到该结果。但是,一些工具也有帮助。例如,“dapper”允许语法调整:

var names = new List<string> { "A", "B", "C" };

var users = connection.Query<User>(
    "select * from users where name in @names",
    new { names }).ToList();

库使用多个参数将其扩展为正确的“in”查询。