以下是实现可选过滤器的方法:
Dim sql = <sql>
SELECT *
FROM MyTable
WHERE (@Column1A IS NULL OR Column1 = @Column1B)
AND (@Column2A IS NULL OR Column2 = @Column2B)
</sql>
command.CommandText = sql.Value
Dim filter1 = If(TextBox1.TextLength = 0, CObj(DBNull.Value), TextBox1.Text)
Dim filter2 = If(TextBox2.TextLength = 0, CObj(DBNull.Value), TextBox2.Text)
With command.Parameters
.Add("@Column1A", OleDbType.VarChar, 50).Value = filter1
.Add("@Column1B", OleDbType.VarChar, 50).Value = filter1
.Add("@Column2A", OleDbType.VarChar, 50).Value = filter2
.Add("@Column2B", OleDbType.VarChar, 50).Value = filter2
End With
首先,注意使用 XML 文字使 SQL 代码更具可读性。其次,注意使用参数将值插入代码而不是字符串连接。
至于实际的过滤,我们来看一对参数:
@Column1A IS NULL OR Column1 = @Column1B
如果TextBox1 为空,则@Column1A 和@Column1B 都设置为NULL。这意味着第一个条件为真并且每一行都匹配,有效地忽略了该过滤器。如果TextBox1 不为空,则第一个条件为假,只有第二个条件为真的那些行才会匹配,从而尊重该过滤器。
值得注意的是,您需要四个参数,因为您使用的是 Access。 Jet 和 ACE OLE DB 提供程序使用位置参数,即使您使用名称。这意味着一个OleDbParameter 不能用于多个SQL 参数。如果您使用的是 SQL Server,那么两个参数就足够了,因为每个参数都可以使用两次,即
Dim sql = <sql>
SELECT *
FROM MyTable
WHERE (@Column1 IS NULL OR Column1 = @Column1)
AND (@Column2 IS NULL OR Column2 = @Column2)
</sql>
command.CommandText = sql.Value
Dim filter1 = If(TextBox1.TextLength = 0, CObj(DBNull.Value), TextBox1.Text)
Dim filter2 = If(TextBox2.TextLength = 0, CObj(DBNull.Value), TextBox2.Text)
With command.Parameters
.Add("@Column1", SqlDbType.VarChar, 50).Value = filter1
.Add("@Column2", SqlDbType.VarChar, 50).Value = filter2
End With