【问题标题】:Pass unknown number of values to select statement将未知数量的值传递给 select 语句
【发布时间】:2022-01-09 23:15:43
【问题描述】:

我有一个部门表,我想在部门下选择多个复选框,然后在数据网格中显示它。当我选择一个选项时,它可以工作,但是如何传递多个值?如queryBuilder图片WHERE userGroup=?所示。

这里我想根据复选框传递多个值:

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    使用STRING_SPLIT

    @values = 'v1,v2,...'
    
    SELECT column_name(s)
    FROM table_name
    WHERE userGroup IN (SELECT value FROM STRING_SPLIT(@values, ','))
    
    【解决方案2】:

    试试 in 子句:https://www.w3schools.com/sql/sql_in.asp

    SELECT column_name(s)
    FROM table_name
    WHERE column_name IN (value1, value2, ...);
    

    你的情况

    WHERE userGroup in (?,?, ... ,?)
    

    这有点棘手,因为您需要每次通过代码创建 sql 语句,具体取决于用户组中的项目。

    不要忘记继续使用参数来保持所有甜蜜的消毒。

    在这里查看如何使用代码:Building SQL "where in" statement from list of strings in one line?

    【讨论】:

    • 我没有图像中显示的特定值,例如我检查了手术和药房我将传递给方法手术和药房的 id,我想我想传递值列表来选择声明,但如何
    • 检查更新的答案
    • 这项工作 WHERE userGroup in (?,?, ... ,?) 但我需要将字符串作为值传递 SELECT [user].userid, [user].Name, user_group.gName FROM ([user] INNER JOIN user_group ON [user].User_Group = user_group.id) WHERE ([user].User_Group IN (SPLIT('2,3,5,7', ' '))) 这需要一些修复它说在查询生成器中未定义的函数“SPLIT”
    【解决方案3】:

    一个选项是使用actual parameters 即时构建WHERE IN 条件,而不是传递文本。下面提供的代码适用于 SQL-Server,存储库中也有代码可用于与 OleDb 提供程序一起使用。

    注意 使用 C#9、.NET Core 5 编码。如果使用较低的框架,例如4.8 则需要修改DataOperations类中的using声明。

    完整代码可在以下 GitHub repository 中找到。

    位于类项目中用于创建带参数的 WHERE IN 的基本代码

    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;
    
    namespace SqlCoreUtilityLibrary.Classes
    {
        public static class SqlWhereInParamBuilder
        {
            /// <summary>
            /// Creates parameters for IN of the WHERE clause
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="partialClause">SELECT partly built up to WHERE IN ({0})</param>
            /// <param name="pPrefix">Prefix for parameter names</param>
            /// <param name="parameters">Parameter values</param>
            /// <returns></returns>
            public static string BuildInClause<T>(string partialClause, string pPrefix, IEnumerable<T> parameters)
            {
                string[] parameterNames = parameters.Select((paramText, paramNumber) 
                    => $"@{pPrefix}{paramNumber}").ToArray();
    
                var inClause = string.Join(",", parameterNames);
                var whereInClause = string.Format(partialClause.Trim(), inClause);
    
                return whereInClause;
    
            }
            /// <summary>
            /// Populate parameter values
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="cmd">Valid command object</param>
            /// <param name="pPrefix">Prefix for parameter names</param>
            /// <param name="parameters">Parameter values</param>
            public static void AddParamsToCommand<T>(this SqlCommand cmd, string pPrefix, IEnumerable<T> parameters)
            {
                var parameterValues = parameters.Select((paramText) => 
                    paramText.ToString()).ToArray();
    
                var parameterNames = parameterValues.
                    Select((paramText, paramNumber) 
                        => $"@{pPrefix}{paramNumber}").ToArray();
    
                 
                for (int index = 0; index < parameterNames.Length; index++)
                {
                    cmd.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = parameterNames[index],
                        SqlDbType = SqlTypeHelper.GetDatabaseType(typeof(T)),
                        Value = parameterValues[index]
                    });
                }
            }
        }
    }
    

    在这种情况下,将所有公司从 SQL-Server 数据库表读取到 CheckedListBox 的表单代码。使用一个按钮,获取每个选中的公司的密钥。

    SELECT 语句显示在标签中,结果显示在列表框中。

    表格代码

    using System;
    using System.Linq;
    using System.Windows.Forms;
    using SimpleExamples.Classes;
    using SimpleExamples.Extensions;
    
    namespace SimpleExamples
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                Shown += OnShown;
    
                DataOperations.GetCommandText += ReceiveQuery;
            }
    
            /// <summary>
            /// Show decoded SQL SELECT
            /// </summary>
            /// <param name="sender"></param>
            private void ReceiveQuery(string sender)
            {
                label1.Text = sender;
            }
    
            private void OnShown(object sender, EventArgs e)
            {
                CompanyCheckedListBox.DataSource = DataOperations.GetCompanies();
            }
    
            private void GetSelectedButton_Click(object sender, EventArgs e)
            {
                CompanyListBox.DataSource = null;
    
                var list = CompanyCheckedListBox.CheckedList();
    
                if (list.Count <= 0) return;
                var indices = list.Select(company => company.Id).ToList();
    
                var (companies, exception) = DataOperations.GetByPrimaryKeys(indices);
                if (exception is null)
                {
                    CompanyListBox.DataSource = companies;
                }
                else
                {
                    MessageBox.Show(exception.Message);
                }
            }
        }
    }
    

    从 CheckedListBox 中获取选中公司的语言扩展

    public static class GenericExtensions
    {
        public static List<Company> CheckedList(this CheckedListBox source)
            => source.Items.Cast<Company>()
                .Where((item, index) => source.GetItemChecked(index)).Select(item => item)
                .ToList();
    
    }
    

    公司类

    public class Company
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public override string ToString() => Name;
    
    }
    

    【讨论】:

    • 我正在使用微软访问数据库
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2021-01-19
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多