带有 VB.net 变量字符串条件的动态 SQL 查询
Posted
技术标签:
【中文标题】带有 VB.net 变量字符串条件的动态 SQL 查询【英文标题】:Dynamic SQL Query With VB.net Variables String condition 【发布时间】:2021-02-02 20:40:14 【问题描述】:大家好,可能是一个快速的答案,但我正在努力解决这个问题,认为一定有更好的方法。
如果字符串的条件不为 null 或为空,我有 4 个字符串,我将其添加到查询中,但第一个始终不需要 AND,因此我添加了 WHERE 1 = 1,然后我可以添加 AND ID = @ID 等,因此可以添加所有四个。我错过了什么?
Dim sqlBuilder As New StringBuilder()
'1 = 1 allows an and.
sqlBuilder.Append("SELECT * FROM table WHERE 1=1 ")
If Surname <> "" Then
sqlBuilder.Append(" AND Surname=@surname")
End If
If Payroll <> "" Then
sqlBuilder.Append(" AND payroll = @payroll")
End If
If VehicleReg <> "" Then
sqlBuilder.Append(" AND registration = @registration")
End If
If OrgID > 0 Then
sqlBuilder.Append(" AND OrganisationID = @orgid")
End If
【问题讨论】:
您遇到错误了吗?如果有,那是什么? 你的所作所为对我来说似乎很好,但我建议的唯一一件事是检查你的 builder 的长度,然后只在需要时添加“AND” 没有错误我只是想知道是否有更好的方法。 我个人会坚持使用这个(或其他一些 LINQ 构建的链)而不是一个“上帝查询”。请参阅我对@jmcilhinney 答案的评论了解原因。 【参考方案1】:有一种简单的方法可以使用单个不变的 SQL 查询,同时将参数设为可选,例如
Dim query = "SELECT * FROM Person WHERE (@FirstName IS NULL OR FirstName = @FirstName) AND (@LastName IS NULL OR LastName = @LastName)"
Dim command As New SqlCommand
command.CommandText = query
With command.Parameters
.Add("@FirstName", SqlDbType.VarChar, 50).Value = If(firstNameTextBox.TextLength = 0, CObj(DBNull.Value), firstNameTextBox.Text)
.Add("@LastName", SqlDbType.VarChar, 50).Value = If(lastNameTextBox.TextLength = 0, CObj(DBNull.Value), lastNameTextBox.Text)
End With
通过将参数设置为 NULL,您可以有效地忽略它。例如,如果@FirstName
参数设置为NULL,那么@FirstName IS NULL
为真,并且第一组条件匹配每一行,否则它只匹配那些包含指定名字的行。对于第二组标准也是如此。您可以根据需要对任意多组条件执行相同的操作,将参数与 NULL 或列与参数进行比较。
需要注意的一点是,我在上面的示例中为四个条件使用了两个参数。这是可能的,因为SqlClient
支持真正的命名参数。对于不支持真正命名参数的提供程序,例如OleDb
的 Jet 或 ACE,你实际上需要添加两倍的参数,因为你不能在 SQL 代码中两次使用相同的参数,例如
Dim query = "SELECT * FROM Person WHERE (@FirstName1 IS NULL OR FirstName = @FirstName2) AND (@LastName1 IS NULL OR LastName = @LastName2)"
Dim command As New OleDbCommand
command.CommandText = query
Dim firstName = If(firstNameTextBox.TextLength = 0, CObj(DBNull.Value), firstNameTextBox.Text)
Dim lastName = If(lastNameTextBox.TextLength = 0, CObj(DBNull.Value), lastNameTextBox.Text)
With command.Parameters
.Add("@FirstName1", SqlDbType.VarChar, 50).Value = firstName
.Add("@FirstName2", SqlDbType.VarChar, 50).Value = firstName
.Add("@LastName1", SqlDbType.VarChar, 50).Value = lastName
.Add("@LastName2", SqlDbType.VarChar, 50).Value = lastName
End With
【讨论】:
唯一的麻烦是不同的情况很可能有不同的最优计划。使用这种方法,优化器可能会根据第一个参数选择一个计划并坚持下去。通过根据原始提供的参数创建 SQL,您可以在每种情况下获得一个计划,这几乎肯定会更好。以上是关于带有 VB.net 变量字符串条件的动态 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
SQL 查询字符串在 SQL Server Management Studio 中有效,但在带有 SQLCommand.ExecuteReader 的 VB.net 中无效
使用带有 ADO 的 Excel 2010 VBA(或带有 LINQ 的 vb.net)查询表的最佳 SQL 语句是啥