SQL使用逗号分隔值和IN子句

use*_*944 6 sql-server asp.net

我正在开发一个ASP.NET应用程序,并将一个字符串值"1,2,3,4"传递给一个过程,以选择那些IN(1,2,3,4)的值,但它说"转换失败时转换varchar值'1,2,3,4'到数据类型int."

这是aspx代码:

private void fillRoles()
{
    /*Read in User Profile Data from database */
    Database db = DatabaseFactory.CreateDatabase();

    DbCommand cmd = db.GetStoredProcCommand("sp_getUserRoles");

    db.AddInParameter(cmd, "@pGroupIDs", System.Data.DbType.String);
    db.SetParameterValue(cmd, "@pGroupIDs", "1,2,3,4");

    IDataReader reader = db.ExecuteReader(cmd);

    DropDownListRole.DataTextField = "Group";
    DropDownListRole.DataValueField = "ID";

    while (reader.Read())
    {
        DropDownListRole.Items.Add((new ListItem(reader[1].ToString(), reader[0].ToString())));
    }

    reader.Close();
}
Run Code Online (Sandbox Code Playgroud)

这是我的程序:

CREATE Procedure [dbo].[sp_getUserRoles](@pGroupIDs varchar(50))
AS BEGIN
   SELECT * FROM CheckList_Groups Where id in (@pGroupIDs)
END
Run Code Online (Sandbox Code Playgroud)

Dra*_*cir 11

这是workaround我发现你要做的事情

CREATE Procedure [dbo].[sp_getUserRoles](
   @pGroupIDs varchar(50)
    )
     As
    BEGIN
        SELECT * FROM CheckList_Groups Where (',' + @pGroupIDs +',' LIKE '%,' + CONVERT(VARCHAR, id) + ',%')
   End
Run Code Online (Sandbox Code Playgroud)

这得到您的逗号分隔的列表,并将其与该ID的(这是表示像这样',1,',',2,'使用表等)LIKE

  • 我不认为这个解决方案在大型数据集上表现良好,因为在这种情况下不能使用索引.(当使用通配符为like-expression的search-argument添加前缀时,不能使用索引). (2认同)

Jam*_*iec 8

如果您不想使用动态sql,我发现的最好方法是创建一个将分隔的字符串转换为表的函数,类似这样的函数用于整数列表:

CREATE FUNCTION [dbo].[StringToIntList]
(@str VARCHAR (MAX), @delimeter CHAR (1))
RETURNS 
    @result TABLE (
        [ID] INT NULL)
AS
BEGIN

    DECLARE @x XML 
    SET @x = '<t>' + REPLACE(@str, @delimeter, '</t><t>') + '</t>'

    INSERT INTO @result
    SELECT DISTINCT x.i.value('.', 'int') AS token
    FROM @x.nodes('//t') x(i)
    ORDER BY 1

RETURN
END
Run Code Online (Sandbox Code Playgroud)

然后在你的sp中使用它:

CREATE Procedure [dbo].[sp_getUserRoles](
   @pGroupIDs varchar(50)
    )
     As
    BEGIN
        SELECT * FROM CheckList_Groups Where id in (
           SELECT ID FROM dbo.StringToIntList(@pGroupIds,',')
       )
   End
Run Code Online (Sandbox Code Playgroud)


Jah*_*ine 6

当然不能那样做,

生成的查询将是这样的

SELECT * FROM CheckList_Groups Where id in ('1,2,3,4')
Run Code Online (Sandbox Code Playgroud)

并确定它无法执行.

您可以在存储过程中构建查询,然后执行它 exec

'SELECT * FROM CheckList_Groups Where id in (' + @pGroupIDs + ')'
Run Code Online (Sandbox Code Playgroud)

要么

SELECT * FROM CheckList_Groups Where charindex(','+id+',' , @pGroupIDs)>0
Run Code Online (Sandbox Code Playgroud)

但首先必须','在c#代码中添加参数的开头和结尾