VFP数据访问层怎么选?DAL_CA vs MSSQLHelper终极对比
做VFP开发,数据访问层选什么?是选重量级的DAL_CA,一个类搞定增删查改?还是选轻量级的MSSQLHelper,SQL命令一把梭?
今天我们就把这两个方案掰开揉碎来对比,帮你做出最合适的选择。
一、先看两个方案的本质
MSSQLHelper:轻量级选手
MSSQLHelper是SQL命令的封装类,核心思路很简单——把SQL语句扔进去,拿到结果。
特点:无需管连接,执行失败能获取具体错误信息。很多狐友写程序喜欢用SQLEXEC(),执行失败就笼统提示"执行失败",而不去跟踪和处理错误,这是要不得的。
核心方法:
|
方法 |
功能 |
返回值 |
|---|---|---|
SQLQuery(cSQL, cCursor) |
查询数据到游标 |
记录数,-1表示出错 |
GetSingle(cSQL) |
返回单值(第一行第一列) |
数值或出错时为空 |
ExecuteSQL(cSQL) |
执行增删改 |
影响记录数,-1表示出错 |
GetMaxID(cField, cTable) |
获取字段最大值 |
逻辑值 |
ColumnExists(cField, cTable) |
判断字段是否存在 |
逻辑值 |
错误信息统一存放在 errmsg 属性中。
DAL_CA:重量级选手
DAL_CA基于VFP本身的CursorAdapter派生,是重量级的DAL层类。一个类一经实例化,即拥有增删改保存撤销的全部方法,C/S和B/S模式都可以使用。
特点:CursorFill后生成临时表,像VFP的临时表一样操作,也可以绑定到控件中操作。
核心方法:
|
方法 |
功能 |
|---|---|
CursorFill(.T.) |
查询所有记录到临时表 |
Add() |
新增一个空行 |
Replace ... in (oDALCA.alias) |
修改数据行 |
Delete() |
删除当前行 |
Save() |
保存到后台数据库(.T.成功,.F.查看msg属性) |
Undo() |
撤消所有操作 |
DetectChanged() |
检查数据是否被修改(返回.T.则被修改过) |
ParseJSON(JSON, 所属, 0, 主键list) |
加载JSON变成临时表 |
二、代码对比:同一个需求两种写法
需求1:查询雇员表
MSSQLHelper写法:
oDBSQLhelper = NEWOBJECT("MSSQLHelper", "MSSQLHelper.prg")
nRow = oDBSQLhelper.SQLQuery("select * from Employees", "Employees")
IF nRow < 0
? oDBSQLhelper.errmsg
ENDIF
BROWSE
DAL_CA写法:
oDALCA = NEWOBJECT("DAL_Employees", "dal_employees.prg")
oDALCA.CursorFill(.T.)
BROWSE
💡 DAL_CA需要先有代码生成器生成的PRG文件,MSSQLHelper直接写SQL更灵活。
需求2:修改记录
MSSQLHelper写法:
oDBSQLhelper = NEWOBJECT("MSSQLHelper", "MSSQLHelper.prg")
? oDBSQLhelper.ExecuteSQL("update Employees set LastName='张三' where EmployeeID=1")
DAL_CA写法:
oDALCA.Add() && 新增空行
REPLACE lastname WITH '中国' IN (oDALCA.alias) && 修改数据
oDALCA.Delete() && 删除当前行
IF !oDALCA.Save() && 保存到数据库
WAIT WINDOW oDALCA.msg && 失败时查看错误
ENDIF
需求3:获取单值(如记录数)
MSSQLHelper写法:
oDBSQLhelper = NEWOBJECT("MSSQLHelper", "MSSQLHelper.prg")
? oDBSQLhelper.GetSingle("select count(*) from Employees")
DAL_CA写法: 需要先CursorFill再RECCOUNT(),不如GetSingle方便。
三、参数传递:MSSQLHelper的三种方式
MSSQLHelper支持三种参数传递方式,灵活度很高:
方式1:变量绑定(?传参,防SQL注入)
PRIVATE myvar
myvar = "张三"
lcSQLCmd = "select * from username where username=?myvar"
oDBSQLhelper = NEWOBJECT("MSSQLHelper", "MSSQLHelper.prg")
nRow = oDBSQLhelper.SQLQuery(lcSQLCmd, "Employees")
方式2:TEXTMERGE拼接
myvar = "张三"
TEXT TO lcSQLCmd NOSHOW ADDITIVE TEXTMERGE PRETEXT 1+2
select * from username where username = "<<myvar>>"
ENDTEXT
方式3:StringFormat格式化
lcWhere = StringFormat("name='{2}' And 单位名称='{1}'", "北京", "张三")
lcSQLCmd = "select * from username where " + lcWhere
⚠️ 推荐方式1(变量绑定),既安全又简洁,还能防止SQL注入。
四、多账套连接管理
MSSQLHelper支持自定义连接句柄,多账套场景很方便:
* 通过账套名创建连接
oCon = NEWOBJECT("qiyu_connection", "qiyu超类", "", "jcbg") && 第四个参数为账套名
nCon = oCon.CreateCon() && 创建连接句柄
* 传入自定义句柄复用连接
oDBSQLhelper = NEWOBJECT("MSSQLHelper", "MSSQLHelper.prg", "", nCon)
oDBSQLhelper.SQLQuery("select * from Orders", "Orders")
DAL类也可以复用句柄的。
五、选型决策表
|
维度 |
MSSQLHelper |
DAL_CA |
|---|---|---|
| 定位 |
轻量级SQL封装 |
重量级ORM |
| 上手难度 |
★★☆ 低,写SQL就行 |
★★★ 需生成器配合 |
| 增删查改 |
手写SQL |
内置方法,开箱即用 |
| 绑定控件 |
需手动处理 |
临时表天然支持 |
| 撤销操作 |
不支持 |
Undo()一键撤销 |
| 变化检测 |
不支持 |
DetectChanged() |
| JSON支持 |
不支持 |
ParseJSON() |
| 错误处理 |
errmsg属性 |
msg属性 |
| 灵活性 |
★★★★ 高 |
★★★ 中 |
| 适合场景 |
查询为主、报表统计 |
表单CRUD、数据录入 |
六、我的建议
- 查询为主、报表统计
→ 选MSSQLHelper,写SQL快、灵活、GetSingle方便
- 表单录入、增删改为主
→ 选DAL_CA,内置方法省代码、支持撤销和变化检测
- 混合场景
→ 两个一起用!查询用MSSQLHelper,录入用DAL_CA
在祺佑框架中,MSSQLHelper和DAL_CA不是非此即彼的关系,而是各有擅长的工具。选对工具,开发效率翻倍。
互动时间
你的VFP项目用的是MSSQLHelper还是DAL_CA?或者两者混用?欢迎评论区聊聊你的选择!
觉得这篇有用,点赞+收藏,下次选型直接翻 ⭐
相关阅读:
- 从两层到三层架构:VFP老项目升级实战
- VFP报错速查指南:1604/1871/2090
作者:VFP技术社区 | 转载请注明出处
更多推荐

所有评论(0)