从列表框控件构建 SQL IN 语句 Return 无
Building SQL IN statement from listbox control Return Nothing
我有一个包含多个 select 值的列表框。我正在尝试从员工 table 获取数据。根据我尝试在语句中使用的此 ListBox 的值。我检查了查询,它是真实的,但仍然没有获取任何数据而没有任何错误。
代码如下:
StringBuilder sb = new StringBuilder("SELECT * FROM Emp_Attend LEFT JOIN Employees on Emp_Attend.Emp_ID = Employees.EmpID WHERE ");
StringBuilder sb = new StringBuilder("SELECT * FROM Emp_Attend LEFT JOIN Employees on Emp_Attend.Emp_ID = Employees.EmpID WHERE ");
using (SqlCommand cmdSQL = new SqlCommand())
{
sb.Append("Emp_Attend.Emp_Name IN (");
string InPartQuery = string.Join(",", ListBox1.Items
.Cast<ListItem>()
.Where(t => t.Selected)
.Select(r => "'" + r.Text + "'"));
sb.Append(InPartQuery);
sb.Append(")");
cmdSQL.CommandText = sb.ToString();
cmdSQL.Connection = sqlcon;
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
DataTable dtbl = new DataTable();
da.Fill(dtbl);
sqlcon.Close();
gvEmployees.DataSource = dtbl;
gvEmployees.DataBind();
您可以获得所有选定的项目并将它们存储在一个变量中,然后在您的命令中使用它,如下所示:
List<string> ids = new List<string>();
foreach (var item in listBox1.SelectedItems)
{
ids.Add(item.ToString());
}
string command = $"SELECT * FROM Emp_Attend LEFT JOIN Employees on Emp_Attend.Emp_ID = Employees.EmpID WHERE Emp_Attend.Emp_Name in ({string.Join(",",ids)})";
但我建议您将其参数化以避免 SQL Injection
最好的办法是使用参数而不是字符串连接。以下代码可以在我的GitHub repository were the following class project provides methods to create parameters and the frontend project中找到。
以下内容可能显得过分,因为使用参数会使参数 safe/hidden 中的数据不被窥探。所有代码都可以通过下面 post 中的链接在 GitHub 上获得。在下面的屏幕截图中,前两个示例未参数化,而第三个(按钮硬编码)已完全参数化。
下面的 class method 将生成一个 SQL WHERE IN 没有参数但处理格式,例如apost字符串中的 rophes,单独保留数字。
在下面的截图中,两个组框演示了上面的内容。
对于参数化,有 BuildWhereInClause(string partialClause, string paramPrefix, IEnumerable parameters). Where in the following code sample BuildWhereInClause creates the SQL while AddParamsToCommand 为生成
的 SQL 语句创建参数
SELECT C.CustomerIdentifier , C.CompanyName , C.ContactName , C.ContactTypeIdentifier , FORMAT(C.ModifiedDate, 'MM-dd-yyyy', 'en-US') AS ModifiedDate, CT.ContactTitle FROM dbo.Customers AS C INNER JOIN dbo.ContactType AS CT ON C.ContactTypeIdentifier = CT.ContactTypeIdentifier WHERE CT.ContactTitle IN (@CTContactTitle0,@CTContactTitle1) ORDER BY C.CompanyName
我有一个包含多个 select 值的列表框。我正在尝试从员工 table 获取数据。根据我尝试在语句中使用的此 ListBox 的值。我检查了查询,它是真实的,但仍然没有获取任何数据而没有任何错误。
代码如下:
StringBuilder sb = new StringBuilder("SELECT * FROM Emp_Attend LEFT JOIN Employees on Emp_Attend.Emp_ID = Employees.EmpID WHERE ");
StringBuilder sb = new StringBuilder("SELECT * FROM Emp_Attend LEFT JOIN Employees on Emp_Attend.Emp_ID = Employees.EmpID WHERE ");
using (SqlCommand cmdSQL = new SqlCommand())
{
sb.Append("Emp_Attend.Emp_Name IN (");
string InPartQuery = string.Join(",", ListBox1.Items
.Cast<ListItem>()
.Where(t => t.Selected)
.Select(r => "'" + r.Text + "'"));
sb.Append(InPartQuery);
sb.Append(")");
cmdSQL.CommandText = sb.ToString();
cmdSQL.Connection = sqlcon;
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
DataTable dtbl = new DataTable();
da.Fill(dtbl);
sqlcon.Close();
gvEmployees.DataSource = dtbl;
gvEmployees.DataBind();
您可以获得所有选定的项目并将它们存储在一个变量中,然后在您的命令中使用它,如下所示:
List<string> ids = new List<string>();
foreach (var item in listBox1.SelectedItems)
{
ids.Add(item.ToString());
}
string command = $"SELECT * FROM Emp_Attend LEFT JOIN Employees on Emp_Attend.Emp_ID = Employees.EmpID WHERE Emp_Attend.Emp_Name in ({string.Join(",",ids)})";
但我建议您将其参数化以避免 SQL Injection
最好的办法是使用参数而不是字符串连接。以下代码可以在我的GitHub repository were the following class project provides methods to create parameters and the frontend project中找到。 以下内容可能显得过分,因为使用参数会使参数 safe/hidden 中的数据不被窥探。所有代码都可以通过下面 post 中的链接在 GitHub 上获得。在下面的屏幕截图中,前两个示例未参数化,而第三个(按钮硬编码)已完全参数化。
下面的 class method 将生成一个 SQL WHERE IN 没有参数但处理格式,例如apost字符串中的 rophes,单独保留数字。
在下面的截图中,两个组框演示了上面的内容。
对于参数化,有 BuildWhereInClause(string partialClause, string paramPrefix, IEnumerable parameters). Where in the following code sample BuildWhereInClause creates the SQL while AddParamsToCommand 为生成
的 SQL 语句创建参数SELECT C.CustomerIdentifier , C.CompanyName , C.ContactName , C.ContactTypeIdentifier , FORMAT(C.ModifiedDate, 'MM-dd-yyyy', 'en-US') AS ModifiedDate, CT.ContactTitle FROM dbo.Customers AS C INNER JOIN dbo.ContactType AS CT ON C.ContactTypeIdentifier = CT.ContactTypeIdentifier WHERE CT.ContactTitle IN (@CTContactTitle0,@CTContactTitle1) ORDER BY C.CompanyName