SQL语句的替代方案
本节的内容,可以参考CaseStudy目录下的文件:自动输入后台数据.Table
Foxtable对于SQL语句的依赖,远远低于其它开发工具,因为Foxtable的DataTable提供了一系列处理后台数据的方法,包括:
SQLCompute | 计算后台所有数据 |
SQLReplaceFor | 批量更新后台数 |
SQLDeleteFor | 批量删除后台数据 |
SQLSelect | 从后台查询数据 |
SQLUpdate | 保存通过SQLSelect查询得到的数据 |
SQLFind | 从后台查找数据 |
SQLGetValues | 从后台的指定列中提取不重复值,以集合的形式返回 |
SQLGetComboListString | 从后台的指定的列中提取不重复的值,用符号"|"将这些值连接成一个字符串,并返回这个字符串 |
这些方法的使用非常简单,可以部分代替原来需要试用SQL语句的场合,其局限在于:
1、必须基于DataTable运行,所以表必须已经加载,当然可以只加载表结构,不加载任何数据。
2、不支持事务和异步函数。
我们之前讲述过一个用SQL语句实现自动输入的例子,参考:用SQL语句实现自动输入
接下来我们不用SQL语句,采用上面的方法来实现同样的功能,且同样不加载行政区域表的数据 ,你会看到新的方法代码要简洁很多。
设计步骤:
1、在BeforeLoadInnerTable中设置代码:
If
e.DataTableName
= "行政区域" Then
e.Filter
= "[_Identify] Is Null"
End
If
这个项目中的行政区域表是内部数据表,上述的代码使得打开项目后,行政区域表不会加载任何数据。
如果是外部表,参考: BeforeLoadOuterTable
2、省市列的列表项目是固定的,在项目事件AfterOpenProject加入代码:
Tables("客户").Cols("省市").Combolist
= DataTables("行政区域").SQLGetComboListString("省市")
' Tables("行政区域").Visible = True '实际使用的时候,可以启用此行代码,以隐藏行政区域表
这样打开项目后,会从后台的行政区域表提取不重复的省市值作为客户表省市列的列表项目,尽管行政区域表并没有加载数据。
3、在客户表的PrepareEdit事件中加入代码:
If
e.IsFocusCell
Then '如果是焦点单元格
If
e.Col.Name
= "县市" Then
'如果正在编辑的是县市列
e.Col.Combolist
= DataTables("行政区域").SQLGetComboListString("县市",
"[省市] = '" &
e.Row("省市")
& "'")
End
If
End
If
这样在编辑客户表的县市列之前,会从后台的行政区域表提取该省市的县市值,作为县市列的列表项目使用。
4、最后将客户表DataColChanged事件的代码设置为:
If
e.DataCol.Name
= "省市" OrElse
e.DataCol.Name
= "县市" Then
Dim
dr
As DataRow =
e.DataRow
Dim
sr
As DataRow
sr =
DataTables("行政区域").SQLFind("[省市]
= '" & dr("省市")
& "' And [县市] = '"
& dr("县市")
& "'")
'在后台查找符合条件的行
If
sr
IsNot Nothing
Then '如果找到了符合条件的行
dr("区号")
= sr("区号")
dr("邮编")
= sr("邮编")
Else
dr("区号")
= Nothing
dr("邮编")
= Nothing
End
If
End
If
这样一旦在客户表的某行输入省市和县市两列内容后,会从后台的行政区域表查找对应的行,如果找到,则将该行的区号和邮编写入客户表中,否则清除区号和邮编。
从这个例子可以看出,采用Foxtable内置的处理后台数据的方法,和直接编写SQL语句相比,代码要简洁得多,也不需要改变原来的编程习惯。
另一种执行方式
前面已经提到Foxtable所有后台数据处理函数,都要基于DataTable运行,所以上面的示例中,我们加载了一个空的行政区域表,然后基于此空表处理后台的行政区域表的数据。
虽然我们可以通过代码在Foxtale的主界面中隐藏这个空表,但还是有一定程度的不便,而且有较多数量只需后台处理不需要加载数据的表时,还会加大系统对资源的消耗。
如果愿意,我们可以考虑另一种方式,通过SQL语句生成一个临时表,基于这个临时表执行后台数据处理方法。
首先我们在全局代码中定义一个变量:
Public xzqy As DataTable
然后在AfterOpenProject事件中加上代码:
Dim
cmd As
New
SQLCommand
cmd.ConnectionName
= "数据源名称"
cmd.CommandText
= "SELECT * From {行政区域} Where
[省市] Is Null"
xzqy =
cmd.ExecuteReader
上面的代码生成一个空的临时表,保存在全局变量xzqy中,这个临时表对应后台的行政区域表。
现在我们就可以通过此临时表处理后台的行政区域表的数据了,例如:
Tables("客户").Cols("省市").Combolist = xzqy.SQLGetComboListString("省市")
需要注意,如果不单单是调用后台数据,还要向后台写入数据,生成临时表的时候,必须给ExecuteReader加上参数True,例如:
Dim
cmd As
new
SQLCommand
cmd.ConnectionName
= "数据源名称"
cmd.CommandText
= "Select * From {表名} Where
[_Identify] Is Null"
Dim
dt As
DataTable = cmd.ExecuteReader(True)
当然表必须有主键,才能更新其数据。
关于这种执行方式的更全面的例子,可以参考:自定义用户管理之二