Visual Studio 2017 VB.NET用Dataset与表适配器实现基于服务的数据库动态列查询问题
实现方案说明
SQL 参数化查询不支持直接将列名、表名这类查询结构元素作为参数传入,参数仅可用于传递查询条件的数值。不过你的场景可以通过安全拼接列名的方式实现,具体方案如下:
前置准备
- 将第二个组合框(零件选择框)的
DropDownStyle属性设置为DropDownList,禁止用户手动输入内容,仅可从你预设的选项中选择 - 组合框的选项值直接绑定数据表对应的列名(Part1、Part2、Part3...),显示文本可自定义为更友好的名称(比如"一号零件"对应值"Part1"),从根源避免非法列名的问题
实现方式
方式1:直接编写自定义查询语句(推荐,更灵活)
代码示例如下:
// 获取两个组合框的选中值 string selectedModel = comboBox1.SelectedValue.ToString(); string selectedPartCol = comboBox2.SelectedValue.ToString(); // 拼接查询语句,列名用方括号包裹避免关键字冲突 string querySql = $"SELECT [{selectedPartCol}] FROM 你的表名 WHERE Model = @SelectedModel"; // 执行查询 using (SqlConnection conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); using (SqlCommand cmd = new SqlCommand(querySql, conn)) { // 型号参数用参数化传入,避免注入 cmd.Parameters.AddWithValue("@SelectedModel", selectedModel); object queryResult = cmd.ExecuteScalar(); if (queryResult != null) { // 得到对应零件编号,可直接赋值给显示控件 string partNumber = queryResult.ToString(); } } }
方式2:复用已创建的表适配器
如果你不想改动已有的DataSet和表适配器结构,可以动态修改表适配器的查询命令文本:
// 实例化你已经创建好的表适配器 var tableAdapter = new 你的数据集名称TableAdapters.你的表名TableAdapter(); string selectedPartCol = comboBox2.SelectedValue.ToString(); // 动态修改查询语句 tableAdapter.Adapter.SelectCommand.CommandText = $"SELECT [{selectedPartCol}] FROM 你的表名 WHERE Model = @SelectedModel"; // 传入型号参数执行查询 var resultTable = tableAdapter.GetDataBy(comboBox1.SelectedValue.ToString()); if (resultTable.Rows.Count > 0) { string partNumber = resultTable.Rows[0][0].ToString(); }
注意事项
- 拼接列名前一定要校验选中值是否在你预设的合法列名列表中,进一步规避风险
- 列名外包裹方括号
[]可以避免列名和SQL关键字冲突导致的语法错误
内容的提问来源于stack exchange,提问作者Keith Hyder
相关产品推荐
相关产品推荐

