好的,我认为问题在于假设您不能有“可选”参数,或者您必须提前设置它们。 (你没有)。
你可以去列出这个:
dim strWhere as string
strWhere = "(State = @State)
cmdSQL.Parmaters.Add("@State",SqlDbType.NVarchar).Value = lstBrowse.SelectedItem.Value
现在,我可以“即时”向 strWhere 添加更多条件,并且随着时间的推移将参数添加到 cmdSQL.Parmaters 集合中。
现在,假设你在一些复杂的网格页面上,用户选择了一些东西,现在你需要把这个说传递给另一个表单吗?
Well, it gets a wee bit messy to have:
Keep track of some field names
Keep track of some conditions (=, like, etc.)
Keep track of the parameters
但您当然可以将一个参数列表和一些也匹配该参数的 sql“串”在一起。因此无需使用 EXISTING 参数对 sql 进行硬编码。
现在,另一个问题是您建议不仅要构建一些动态 sql,而且您需要在会话中传递它(或者您想要那种能力)。
好吧,我只想构建一个非常短代码的“集群”,将以上所有内容放入一个非常短且简单的类中。然后将该类 SHOVE 到会话中。
因此,将这一点代码放入项目中的一个标准代码模块中。
公共类 SqlParms
Public cmdSQL As New SqlCommand("", GetCon)
Public Where As String
Private m_SQL As String
Public Sub Add(FieldName As String, Cond As String, FieldValue As Object, Datatype As SqlDbType)
Dim mycond As String
Dim prex As String = "", sufx As String = ""
If Left(Cond, 1) = "%" Then prex = "'%' + "
If Right(Cond, 1) = "%" Then sufx = " + '%'"
mycond = Replace(Cond, "%", "")
If Where <> "" Then Where += " AND "
Where += "(" & FieldName & " " & mycond & " " & prex & "@" & FieldName & sufx & ")"
cmdSQL.Parameters.Add("@" & FieldName, Datatype).Value = FieldValue
End Sub
Public Property SQL As String
Get
Return m_SQL
End Get
Set(value As String)
m_SQL = value & " WHERE " & Where
cmdSQL.CommandText = m_SQL
End Set
End Property
End Class
那么,以上所有内容都可以吗?让您添加一个“字段”、一个“条件”,然后再添加一些。
很简单。
所以,现在在代码中,我可以走了:
Dim MyParms As New SqlParms
Session("MyParms") = MyParms
现在,请注意我们曾经将 session 指向该类?然后我可以在当前的代码位中添加/修改,而不必将 MyParms 汇集/保存/推回 - 它是一个对象,现在它在会话中。
所以,让我们添加你的条件。
MyParms.Add("State", "=", lstBrowse.SelectedItem.Value, SqlDbType.NVarChar)
好的,所以上面不仅添加了,而且在我们的会话中也添加了!!!
好的,假设我们有两个条件,第二个是 ContactID(数据库中的 PK 值 - 因此是整数数据类型)。
好的,我们现在开始:
MyParms.Add("OrganziationID", "=", lstBrowse.SelectedItem.Value, SqlDbType.Int)
或许
MyParms.Add("OrganziationID", "=", droplist1.SelectedValue, SqlDbType.Int)
MyParms.SQL = "SELECT * from tblHotels"
再次:运行上述 1 或 2 条件后的注意事项?它在 session() 中。
好吧,假设我们跳转到了一个新的不同页面。现在我们需要填充一个网格。
代码将是:
请注意下面我们如何不使用新关键字非常非常小心!
Dim MyParms As SqlParms = Session("MyParms")
Dim rst As New DataTable
Using MyParms.cmdSQL
MyParms.cmdSQL.Connection.Open()
rst.Load(MyParms.cmdSQL.ExecuteReader)
End Using
GridView1.DataSource = rst
GridView1.DataBind()
因此,这个小“帮助”例程可以让您构建 where 子句。
它在 session() 中,现在您可以将所有这些内容传递/跳转到另一个页面。
另一件非常有趣但人们常常没有意识到的事情?
您始终可以向 sql 命令对象添加参数,但尚未设置 sql 集。你甚至不需要连接集。
所以,您实际上可以转储上述“帮助程序”例程,并创建一个 sql 命令对象,然后将其推送到会话中。
不管上面的?您不必对 sql 进行预硬编码。这些值可以并且将成为参数安全的(sql 注入安全),即使您要添加“可选”参数,这也适用。唯一的技巧是确保您还使用这些可选参数构建 sql。
所以,如果我这样去:
dim MyParms as new SqlParms
MyParms.Add("City", "Like%", "E", SqlDbType.NVarChar)
MyParms.SQL = "SELECT * from tblHotels"
Dim rst As New DataTable
Using MyParms.cmdSQL
MyParms.cmdSQL.Connection.Open()
rst.Load(MyParms.cmdSQL.ExecuteReader)
End Using
GridView1.DataSource = rst
GridView1.DataBind()
所以上面的内容会用结果表填充我们的数据网格。
上面的sql现在是这样的:
SELECT * from tblHotels WHERE (City Like @City + '%')
现在是因为我想要“点赞”支持吗?好吧,我无法在参数名称中添加/包含/包含 %(我使用与前面带有 @ 的字段名称相同。
所以,我使用 %like(作为前缀通配符)
和 Like%(用于后缀)。然后代码会去掉 % 并将其正确添加到上面的 where 子句中。
因此,您可以/可以在“添加”更多条件时对字符串进行编码。但在所有情况下,使用参数仍然不仅是个好主意,而且做起来也不是那么难。
我在那个类中还使用了一个名为 GetCon 的公共函数,它只返回一个连接对象,但您可以将该类中的“GetCon”替换为您自己的例程,该例程返回一个连接字符串,然后用于创建 sqlconneciton对象。
另外,相当次要,但我确实假设 sql 属性设置为 LAST,因为 sql 字符串随后与 where 子句组合。如果添加更多参数,则需要重新设置 sql 属性。
总结:
您可以并且应该添加附加值作为参数。我没有太多理由不这样做。
如果您需要在一个页面中设置所有这些,然后跳转到另一个页面,那么可以将这个可爱的帮助程序推入会话中。 (或者甚至让当前页面允许说一些额外的过滤。