将多选选定项目传递到 SQL Server 2008

Passing multiselect selected items into SQL Server 2008

我似乎无法在网上找到一个很好的例子。我想要做的是将多选列表框的所有值传递到 SQL 存储过程中,以将它们写入 table.

我知道如果我想将一个选定的值传递给 SQL 我会这样做:

C#:

using (SqlCommand cmd = new SqlCommand("sp_RegisterUser", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
        cmd.Parameters.Add("@UserPreferences", SqlDbType.Char).Value = MatchPrefs.SelectedValue;
        cmd.Parameters.Add("@UserName", SqlDbType.Char).Value = UserName.Text;

    conn.Open();
    cmd.ExecuteNonQuery();

SQL:

ALTER PROCEDURE [dbo].[sp_RegisterUser]
    @UserPreferences varchar(max),
    @UserName varchar(25)

AS
BEGIN

INSERT INTO tmpUserMatch (
    UserID,
    MatchField,
    MatchValue

    )
VALUES (
    (SELECT Top 1 UserID FROM tmpUsers WHERE UserName = @UserName),
    'MatchPreferences',
    @UserPreferences
    )

END     

但是如果 MatchPrefs 是多选的,我该怎么做呢?

编辑

我已将 C# 部分替换为:

cmd.Parameters.Add("@UserPreferences", SqlDbType.Char).Value = MatchPrefs.SelectedValue;

与:

var selectedInterests = MatchPrefs.Items.Cast<ListItem>().Where(item => item.Selected).Select(item => item.Value).ToList();
string strInterests = String.Join(",", selectedInterests).TrimEnd();
cmd.Parameters.Add("@UserPreferences", SqlDbType.Char).Value = strInterests;

并且在 SQL 端我有一个函数将创建一个 table 值参数:

SELECT * FROM dbo.CSVToTable(@UserPreferences)

只需要一些帮助来完成 SQL 方面以及我需要包含的 2 个附加字段;用户 ID 和匹配字段。

  1. 不要使用 sp_ 作为 procs 的前缀(这会损害性能,因为它会导致 SQL 服务器首先查看 [master] 数据库)
  2. 使用SqlDbType.VarChar
  3. 指定最大长度(-1 用于 MAX,但我非常怀疑你甚至需要 8000 个字符)
  4. @UserPreferences 的输入参数定义应具有匹配的最大长度(同样,没有理由使用 MAX
  5. 不要只是为了查找而传入 @UserName。改为传入 @UserID。如果在多个页面上使用它,请事先查找并将其存储在 Session 或 ViewState 中,否则在加载初始页面时获取它。
  6. 为什么要实例化一个 DataAdapter ?
  7. 您的 SQL 拆分函数不会创建 Table 值参数。它只是 returns 一个结果集。
INSERT INTO SchemaName.tmpUserMatch (
    UserID,
    MatchField,
    MatchValue
)
SELECT
    @UserID,
    'MatchPreferences',
    csv.SplitVal
 FROM dbo.SplitCSV(@UserPreferences) csv;

从多选中获取列表:

    private string GetList(ListItemCollection list)
    {
        string separadosporcoma = "";

        if (list.Count > 0)
        {
            foreach (ListItem item in list)
                separadosporcoma += item.Value + ",";
            separadosporcoma = separadosporcoma.TrimEnd(',');
        }
        return separadosporcoma;
    }

在 SQL 服务器中,我使用这个 table 值函数:

ALTER function [dbo].[fn_ParseCSVString]
(
@CSVString  varchar(8000) ,
@Delimiter  varchar(10)
)
returns @tbl table (s varchar(1000))
as
begin
declare @i int ,
    @j int
    select  @i = 1
    while @i <= len(@CSVString)
    begin
        select  @j = charindex(@Delimiter, @CSVString, @i)
        if @j = 0
        begin
            select  @j = len(@CSVString) + 1
        end
        insert  @tbl select substring(@CSVString, @i, @j - @i)
        select  @i = @j + len(@Delimiter)
    end
    return
end

并且在我的 where 子句中的存储过程中,我像这样调用 sql 函数:

ALTER PROCEDURE [dbo].[GetValuesWithList] 
@MyList AS VARCHAR(1000)
SELECT values
FROM MyTable
WHERE items in (SELECT * FROM dbo.fn_ParseCSVString(@MyList, ',') fn_ParseCSVString)))

我认为这可能对您有所帮助。