如何将复选框选中的数据作为字符串参数传递给 SQL 存储过程

胖浩吖_3315

胖浩吖_3315

2026-04-27

597人浏览

原创

如何将复选框选中的数据作为字符串参数传递给 SQL 存储过程

本文详解如何从 jTable 中批量勾选的行提取指定列(如 ref_no)的字符串值,并安全地序列化为逗号分隔字符串,最终作为参数传入后端 WebMethod 及 SQL 存储过程,涵盖前端采集、JSON 传输、服务端反序列化与 SQL 参数化调用全流程。

本文详解如何从 jtable 中批量勾选的行提取指定列(如 `ref_no`)的字符串值,并安全地序列化为逗号分隔字符串,最终作为参数传入后端 webmethod 及 sql 存储过程,涵盖前端采集、json 传输、服务端反序列化与 sql 参数化调用全流程。

在基于 jTable 的账户管理模块中,常需对多行记录执行批量操作(如“Reassign”),其核心前提是准确获取用户勾选行的关键字段(如 ref_no)并以字符串形式提交至后端,进而作为参数调用 SQL 存储过程。以下为完整、健壮、可直接落地的实现方案:

✅ 前端:精准采集 ref_no 字符串数组

jTable 渲染后,每行

包含多个 ,其中 ref_no 对应第 2 列(索引为 1,因 Tag 列为第 0 列)。需避免使用 nth-child(2)(易受隐藏列或动态结构影响),而应通过字段名语义定位:
$("#btnReassign").on("click", function () {
    const checkedBoxes = $('input.chk:checked'); // 使用类选择器更可靠
    const refNos = [];

    checkedBoxes.each(function () {
        const $row = $(this).closest('tr');
        // 安全获取 ref_no:查找 class="jtable-column-ref_no" 的 td 或按列序(推荐前者)
        const $refNoCell = $row.find('td.jtable-column-ref_no');
        if ($refNoCell.length) {
            const refNo = $.trim($refNoCell.text());
            if (refNo) refNos.push(refNo);
        }
    });

    if (refNos.length === 0) {
        alert("请至少选择一行进行重新分配");
        return;
    }

    // 发送至后端 WebMethod
    $.ajax({
        type: "POST",
        url: "List.aspx/ReassignAccounts",
        data: JSON.stringify({ refNos: refNos }),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            if (response.d && response.d.Result === "OK") {
                alert("已成功提交重分配请求");
                $('#TableContainer').jtable('reload'); // 刷新表格
            } else {
                alert("操作失败:" + (response.d?.Message || "未知错误"));
            }
        },
        error: function (xhr, status, err) {
            alert("网络错误:" + err);
        }
    });
});

关键说明:

  • jTable 会自动为每列 添加 class="jtable-column-{fieldName}"(如 jtable-column-ref_no),这是最稳定的选择器;
  • 使用 .text() 提取纯文本值,避免 HTML 标签干扰;
  • 严格校验空值,防止空字符串进入数据库。
  • ✅ 后端:WebMethod 接收并调用存储过程

    新增一个 [WebMethod] 接收字符串数组,并通过参数化方式调用 SQL 存储过程(严禁字符串拼接):

    [WebMethod(EnableSession = true)]
    public static object ReassignAccounts(string[] refNos)
    {
        try
        {
            if (refNos == null || refNos.Length == 0)
                return new { Result = "ERROR", Message = "未提供有效 ref_no 列表" };
    
            // 将字符串数组安全转为逗号分隔字符串(仅用于日志或调试,不用于 SQL 拼接)
            string refNosCsv = string.Join(",", refNos.Select(r => $"'{r.Replace("'", "''")}'"));
    
            // ✅ 正确做法:使用表值参数(TVP)或逐条处理
            // 示例:调用支持 TVP 的存储过程(推荐)
            var result = _repository.NewAccount.ReassignByRefNos(refNos);
            return new { Result = "OK", Message = $"成功处理 {result} 条记录" };
        }
        catch (Exception ex)
        {
            return new { Result = "ERROR", Message = ex.Message };
        }
    }

    ? 存储过程调用建议(C# Repository 层)

    // 使用 DataTable 构造表值参数(TVP)
    public int ReassignByRefNos(string[] refNos)
    {
        using (var conn = new SqlConnection(connectionString))
        {
            conn.Open();
            using (var cmd = new SqlCommand("sp_ReassignAccounts", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
    
                // 构建 TVP
                var tvp = new DataTable();
                tvp.Columns.Add("RefNo", typeof(string));
                foreach (var refNo in refNos)
                    tvp.Rows.Add(refNo);
    
                var param = cmd.Parameters.AddWithValue("@RefNoList", tvp);
                param.SqlDbType = SqlDbType.Structured;
                param.TypeName = "dbo.StringList"; // 需提前在 SQL 中创建 TYPE
    
                return (int)cmd.ExecuteScalar();
            }
        }
    }

    ⚠️ 重要安全提醒:

    • 绝对禁止将 refNos 直接拼入 SQL 字符串(如 "IN ('" + string.Join("','", refNos) + "')"),极易导致 SQL 注入;
    • 表值参数(TVP)是批量传参的黄金标准,兼顾性能与安全性;
    • 若无法使用 TVP,可改用 UNION ALL 动态构建参数化查询,但 TVP 更优。

    ✅ SQL 存储过程示例(使用 TVP)

    -- 1. 创建自定义表类型(只需执行一次)
    CREATE TYPE dbo.StringList AS TABLE (Value NVARCHAR(50) NOT NULL);
    
    -- 2. 存储过程
    CREATE PROCEDURE sp_ReassignAccounts
        @RefNoList dbo.StringList READONLY
    AS
    BEGIN
        SET NOCOUNT ON;
    
        UPDATE a 
        SET RMID = @NewRMID, UpdatedAt = GETDATE()
        FROM Accounts a
        INNER JOIN @RefNoList t ON a.RefNo = t.Value;
    
        SELECT @@ROWCOUNT;
    END

    ✅ 总结与最佳实践

    环节 推荐做法 禁止行为
    前端采集 使用 jtable-column-{field} 类选择器 + .text() 提取;过滤空值 依赖 nth-child() 或 innerHTML
    数据传输 JSON.stringify({ refNos: [...] }) + contentType: "application/json" URL 查询字符串传大量数据
    后端接收 [WebMethod] 接收 string[];验证非空 接收 string 再手动 Split(',')(易被注入)
    SQL 调用 表值参数(TVP)或参数化 IN 子句(如 WHERE RefNo IN (@p1,@p2,...)) 字符串拼接 SQL

    通过以上结构化实现,你不仅能稳定获取复选框数据并转为字符串,更能确保从浏览器到数据库全程符合安全编码规范,杜绝注入风险,同时保持良好的可维护性与扩展性。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
点击input框没有光标怎么办
点击input框没有光标怎么办

点击input框没有光标的解决办法:1、确认输入框焦点;2、清除浏览器缓存;3、更新浏览器;4、使用JavaScript;5、检查硬件设备;6、检查输入框属性;7、调试JavaScript代码;8、检查页面其他元素;9、考虑浏览器兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.24

874

4

点击input框没有光标怎么办
点击input框没有光标怎么办

点击input框没有光标的解决办法:1、确认输入框焦点;2、清除浏览器缓存;3、更新浏览器;4、使用JavaScript;5、检查硬件设备;6、检查输入框属性;7、调试JavaScript代码;8、检查页面其他元素;9、考虑浏览器兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.24

874

4

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

80

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

40

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

40

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

20

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

40

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

20

15

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

2026.10.22

40

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习