Skip to content

链式 CURD - 综合示例与最佳实践

本文包含实战示例、与传统 SQL 对比、常见问题和最佳实践。方法详细说明参见各子页面:


综合示例

示例1:用户管理系统

vb
' 查询活跃用户列表(排序+分页)
If db.Table("users") _
    .Where("status=?", "active") _
    .WhereNotNull("email") _
    .OrderByDesc("last_login") _
    .Page(1, 20) _
    .RowRead Then
    
    Do Until db.Rs.EOF
        Debug.Print db.Rs!name & " | " & db.Rs!email
        db.Rs.MoveNext
    Loop
End If

' 搜索用户(模糊匹配+OR条件)
db.Table("users") _
    .WhereLike("name", "%" & keyword & "%") _
    .OrWhereLike("email", "%" & keyword & "%") _
    .OrderBy("name") _
    .RowRead

' 创建新用户
With db.Table("users")
    .Field "name", txtName.Text
    .Field "age", CLng(txtAge.Text)
    .Field "email", txtEmail.Text
    .Field "status", "active"
    .RowCreate
    newId = db.LastInsertId
End With

' 更新用户信息
With db.Table("users").Where("id=?", userId)
    .Field "name", txtName.Text
    .Field "email", txtEmail.Text
    .RowUpdate
End With

' 删除过期用户
db.Table("users").Where("status=?", "expired").WhereNull("email").RowDelete

示例2:报表统计

vb
' 部门人数统计
db.Table("users") _
    .Columns("dept,COUNT(*) AS cnt") _
    .GroupBy("dept") _
    .Having("cnt>5") _
    .OrderByDesc("cnt") _
    .RowRead

' 月度销售汇总
db.Table("orders") _
    .Columns("YEAR(created_at) AS y,MONTH(created_at) AS m,SUM(amount) AS total") _
    .GroupBy("YEAR(created_at)") _
    .GroupBy("MONTH(created_at)") _
    .WhereBetween("created_at", "2026-01-01", "2026-12-31") _
    .OrderBy("y") _
    .OrderBy("m") _
    .RowRead

' 快速统计
Dim totalUsers As Long
totalUsers = db.Table("users").RowCount

Dim avgSalary As Variant
avgSalary = db.Table("users").Where("dept=?", "IT").RowAvg("salary")

Dim maxOrder As Variant
maxOrder = db.Table("orders").RowMax("amount")

' 获取所有部门名称列表
Dim depts As Collection
Set depts = db.Table("users").Distinct.Columns("dept").RowPluck("dept")

示例3:多表关联查询

vb
' 订单详情(订单+用户+产品)
db.Table("orders") _
    .Columns("orders.id,users.name AS user_name,products.title AS product,orders.amount") _
    .Join("users", "orders.user_id=users.id") _
    .LeftJoin("products", "orders.product_id=products.id") _
    .Where("orders.amount>?", 100) _
    .WhereBetween("orders.created_at", "2026-01-01", "2026-06-30") _
    .OrderByDesc("orders.amount") _
    .Limit(50) _
    .RowRead

示例4:判断存在与提取列表

vb
' 注册前检查邮箱是否已存在
If db.Table("users").Where("email=?", newEmail).RowExists Then
    MsgBox "该邮箱已注册"
    Exit Sub
End If

' 获取管理员ID列表
Dim adminIds As Collection
Set adminIds = db.Table("users").WhereIn("role", "admin,superadmin").RowPluck("id")

' 批量操作:将所有管理员标记为在线
With db.Table("users").WhereIn("id", "1,2,3,5")
    .Field "online_status", True
    .RowUpdate
End With

与传统 SQL 方式对比

查询对比

vb
' ── 传统 SQL 方式 ──
db.Sql("SELECT id,name FROM users WHERE age > 18 AND dept IN ('IT','HR') ORDER BY age DESC LIMIT 10").Fetch

' ── 链式构建器方式 ──
db.Table("users") _
    .Columns("id,name") _
    .Where("age>?", 18) _
    .WhereIn("dept", "IT,HR") _
    .OrderByDesc("age") _
    .Limit(10) _
    .RowRead

插入对比

vb
' ── 传统 SQL 方式 ──
db.Sql("INSERT INTO users (name,age) VALUES ('张三',25)").Exec

' ── 链式构建器方式 ──
db.Table("users").Field("name", "张三").Field("age", 25).RowCreate

更新对比

vb
' ── 传统 SQL 方式 ──
db.Sql("UPDATE users SET name='李四' WHERE id=1").Exec

' ── 链式构建器方式 ──
db.Table("users").Where("id=?", 1).Field("name", "李四").RowUpdate

删除对比

vb
' ── 传统 SQL 方式 ──
db.Sql("DELETE FROM users WHERE status='expired'").Exec

' ── 链式构建器方式 ──
db.Table("users").Where("status=?", "expired").RowDelete

链式优势

维度传统 SQL链式构建器
可读性长字符串拼接,难以阅读方法链语义清晰
SQL 注入风险手动拼接值,容易遗漏转义参数自动转义
跨数据库需手写不同数据库的分页/限制语法自动适配 MySQL/MSSQL/Access
维护性改条件需重写整个 SQL增删链式方法即可
调试需打印完整 SQL每步对应一个 SQL 子句

常见问题

Q1: 链式构建器与 Sql() 方法能混用吗?

不建议混用。链式构建器(Table + Where + ...)和传统方式(Sql)使用不同的内部状态。如果已调用 Sql(),链式条件不会生效;反之亦然。请选择一种方式:

vb
' 方式1:链式构建器(推荐用于标准 CRUD)
db.Table("users").Where("id=?", 1).RowRead

' 方式2:传统 SQL(适合复杂查询、子查询等)
db.Sql("SELECT * FROM users WHERE id = 1").Fetch

Q2: 复杂查询不适合链式怎么办?

对于子查询、UNION、窗口函数等高级 SQL,链式构建器无法覆盖,请使用传统 Sql() 方式:

vb
' 子查询 - 使用 Sql() 方式
db.Sql("SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE amount > 1000)").Fetch

' UNION 查询 - 使用 Sql() 方式
db.Sql("SELECT name FROM users UNION SELECT name FROM admins").Fetch

Q3: Where 和 WhereLike 能同时使用吗?

可以,它们都是 AND 条件,会自动合并:

vb
db.Table("users") _
    .Where("dept=?", "IT") _
    .WhereLike("name", "%张%") _
    .RowRead
' 生成: WHERE dept='IT' AND name LIKE '%张%'

Q4: OrWhere 的优先级如何?

OrWhere 用括号包裹,确保与 AND 条件正确组合:

vb
db.Table("users").Where("age>?", 18).OrWhere("role='VIP'").RowRead
' 生成: WHERE age > 18 OR (role='VIP')

Q5: RowCreate 后能继续使用 Rs 编辑吗?

可以。RowCreate 后不自动重置构建器,允许你继续操作 Rs:

vb
With db.Table("users").RowCreate
    .Rs!name = "张三"
    If someCondition Then
        .Rs!email = "zhang@test.com"
    End If
    .Rs.Update
End With

Q6: Page 和 Limit/Offset 有什么区别?

方法适用场景实现方式
Page(N,M)标准分页ADO PageSize/AbsolutePage,所有数据库通用
Limit(M)简单截断SQL LIMIT M,MySQL/MSSQL 语法适配
Offset(N)配合 Limit偏移SQL OFFSET N,MySQL/MSSQL 语法适配

不要同时使用 Page 和 Limit/Offset,选择其一即可。

Q7: 链式方法执行后状态会保留吗?

不会。终结方法(RowRead, RowCreate, RowUpdate, RowDelete, RowCount 等)执行后会自动调用 ResetBuilder 清除所有内部状态。下次链式调用需要重新从 Table() 开始。


最佳实践

1. 使用 With 简化链式调用

vb
' 推荐:With 结构清晰
With db.Table("users").Where("id=?", userId)
    .Field "name", newName
    .Field "age", newAge
    .RowUpdate
End With

' 不推荐:散开写
db.Table "users"
db.Where "id=?", userId
db.Field "name", newName
db.Field "age", newAge
db.RowUpdate

2. 优先使用链式参数转义

vb
' 推荐:Where 占位符自动转义
db.Table("users").Where("name=?", userName).RowRead

' 不推荐:手动拼接值
db.Table("users").Where("name='" & userName & "'").RowRead

3. 始终为更新/删除设置条件

vb
' 安全:必须有 Where 条件
db.Table("users").Where("id=?", 1).RowUpdate
db.Table("users").Where("status=?", "expired").RowDelete

' 危险:没有条件会报错(构建器保护)
db.Table("users").RowUpdate  ' 报错: no condition set

4. 复杂查询用 Sql()

vb
' 链式适合:标准 CRUD、简单条件、排序、分页
db.Table("users").Where("age>?", 18).OrderByDesc("id").Page(1, 10).RowRead

' Sql() 适合:子查询、UNION、窗口函数、复杂表达式
db.Sql("SELECT * FROM (SELECT id,name FROM users UNION SELECT id,name FROM admins) t").Fetch

最后更新: 2026-06-26

VB6及其LOGO版权为微软公司所有