返回博客列表

SUDB 实战:一个接口,跑遍整个数据库的增删改查

2026年07月07日
apiSQL 团队
SUDB 实战:一个接口,跑遍整个数据库的增删改查

传统的 API 开发中,数据库的每一个查询、每一次写入,往往都要对应一个单独设计、单独发布的 REST 接口。表一多、需求一变,接口数量迅速膨胀,前后端联调成本居高不下。

apiSQL 的 SUDB(Super Database API,超级数据库接口) 提供了另一种思路:用一个 HTTP 接口,承载对整个数据库的增删改查。你只需把 SQL 语句作为文本放进请求体,apiSQL 负责执行并返回结果,无需为每条 SQL 预先定义路由。

本文用 apiSQL 的公开演示环境,通过 curl 实测这一功能,所有请求与响应均为真实运行结果。

一、接口约定

演示环境的 SUDB 接口信息如下:

  • 地址:https://open.apisql.cn/api/demo-area/$sudb
  • 方法:POST
  • 请求头:Content-Type: application/json;charset=UTF-8
  • 鉴权头:Authorization: Bearer <APIKEY>

演示用 API Key 为公开的(这是一个有意开放的演示项目)。建议将其写入环境变量,避免在脚本中硬编码:

export APISQL_DEMO_KEY="sk-93e23231a9c8257f2c21854531f42b0a"

请求体的基本结构:

{
  "meta": {
    "ds": "mysql",              // 数据源名称
    "sc": "SELECT * FROM user", // 要执行的 SQL
    "pageNum": 1,               // 可选:分页页码
    "pageSize": 10              // 可选:每页条数
  },
  "params": {                    // 可选:为 SQL 中的 :命名参数 传值
    "myId": 1001
  }
}

其中 meta.sc 就是 SQL 语句,params 用于安全地传入参数值。

二、查询:SELECT

先来一条最简单的分页查询:

curl -sS -X POST "https://open.apisql.cn/api/demo-area/\$sudb" \
  -H "Content-Type: application/json;charset=UTF-8" \
  -H "Authorization: Bearer $APISQL_DEMO_KEY" \
  --data-binary '{"meta":{"ds":"mysql","sc":"SELECT * FROM user","pageNum":1,"pageSize":5}}'

返回:

{
  "meta": { "pageMode": true, "totalCount": 20, "offset": 0, "limit": 5, "thisCount": 5 },
  "rows": [
    { "id": 1, "name": "张三", "age": 30 },
    { "id": 2, "name": "李四", "age": 28 },
    { "id": 3, "name": "王五", "age": 50 }
  ]
}

meta 里带回了分页信息(总数 totalCount、本页条数 thisCount),rows 是数据行。

三、命名参数:安全传值

把用户输入拼进 SQL 字符串是 SQL 注入的温床。SUDB 支持 MySQL 命名参数 :name,配合 params 传值:

curl -sS -X POST "https://open.apisql.cn/api/demo-area/\$sudb" \
  -H "Content-Type: application/json;charset=UTF-8" \
  -H "Authorization: Bearer $APISQL_DEMO_KEY" \
  --data-binary '{"meta":{"ds":"mysql","sc":"SELECT id,name,age FROM user WHERE age > :minAge ORDER BY age DESC","pageNum":1,"pageSize":3},"params":{"minAge":30}}'

返回按年龄降序、且年龄大于 30 的前 3 条:

{
  "meta": { "pageMode": true, "totalCount": 7, "offset": 0, "limit": 3, "thisCount": 3 },
  "rows": [
    { "id": 1999, "name": "胡某人", "age": 99 },
    { "id": 1021, "name": "李大爷", "age": 75 },
    { "id": 3, "name": "王五", "age": 50 }
  ]
}

四、增删改:INSERT / UPDATE / DELETE

写操作的请求体结构与查询一致,只是 sc 换成对应的 SQL。演示环境仅 user 表可写,测试时建议用较大的 id(如 8001)并在结束后清理。

新增:

curl -sS -X POST "https://open.apisql.cn/api/demo-area/\$sudb" \
  -H "Content-Type: application/json;charset=UTF-8" \
  -H "Authorization: Bearer $APISQL_DEMO_KEY" \
  --data-binary '{"meta":{"ds":"mysql","sc":"INSERT INTO user(id,name,age) VALUE(:myId,:myName,:myAge)"},"params":{"myId":8001,"myName":"小明","myAge":18}}'

返回写操作的执行摘要:

{ "info": { "affectedRows": 1, "insertId": 8001, "changedRows": 0 },
  "meta": { "affectedRows": 1 }, "rows": [] }

修改:

curl -sS -X POST "https://open.apisql.cn/api/demo-area/\$sudb" \
  -H "Content-Type: application/json;charset=UTF-8" \
  -H "Authorization: Bearer $APISQL_DEMO_KEY" \
  --data-binary '{"meta":{"ds":"mysql","sc":"UPDATE user SET age = :myAge WHERE id = :myId"},"params":{"myId":8001,"myAge":19}}'

返回 "changedRows": 1,表示一行被实际修改。

删除:

curl -sS -X POST "https://open.apisql.cn/api/demo-area/\$sudb" \
  -H "Content-Type: application/json;charset=UTF-8" \
  -H "Authorization: Bearer $APISQL_DEMO_KEY" \
  --data-binary '{"meta":{"ds":"mysql","sc":"DELETE FROM user WHERE id = :myId"},"params":{"myId":8001}}'

一条 SQL 语句、一次请求,完成一次写入或删除。

五、不止 CRUD:聚合、SHOW、DESC

SUDB 执行的是标准 SQL,因此聚合查询、元数据查询同样可用。

聚合统计:

--data-binary '{"meta":{"ds":"mysql","sc":"SELECT COUNT(*) AS total, ROUND(AVG(age),1) AS avg_age FROM user"}}'
{ "meta": { "totalCount": 1, "thisCount": 1 },
  "rows": [ { "total": 20, "avg_age": "32.9" } ] }

查看表结构:

--data-binary '{"meta":{"ds":"mysql","sc":"DESC user"}}'
{ "rows": [
  { "Field": "id",   "Type": "int unsigned",     "Null": "NO", "Key": "PRI", "Extra": "auto_increment" },
  { "Field": "name", "Type": "varchar(100)",     "Null": "NO", "Key": "",    "Extra": "" },
  { "Field": "age",  "Type": "tinyint unsigned", "Null": "NO", "Key": "",    "Extra": "" }
] }

六、安全模型:权限由数据库账号管控

一个能跑任意 SQL 的接口,安全吗?SUDB 的答案是:把授权交给数据库本身

在演示环境中,只有 user 表允许写入。当我们尝试删除其他表的数据时:

--data-binary '{"meta":{"ds":"mysql","sc":"DELETE FROM area WHERE id = 1"}}'

返回:

{ "code": "API_GATEWAY_SERVER_ERROR",
  "message": "DELETE command denied to user 'demo_user1'@'...' for table 'area'" }

这个拒绝来自 MySQL 层,而非 apiSQL 应用层——演示用的数据库账号 demo_user1 本身就没有 area 表的删除权限。这意味着:SUDB 能做什么,由你为它配置的数据库账号权限决定。想让某张表只读,就在数据库里只授予它 SELECT 权限即可。这种设计把权限控制收敛到数据库这一唯一可信来源,清晰且可审计。

同样,SQL 写错了,错误信息也会原样透传,便于定位:

{ "code": "API_GATEWAY_SERVER_ERROR",
  "message": "Table 'demodb1.not_exist_table' doesn't exist" }

七、适用场景

SUDB 这种"一个接口跑 SQL"的模式,在以下场景中较为实用:

  • 快速搭建后端:无需为每个查询设计路由,前端或脚本直接发 SQL 即可拿到数据。
  • AI / Agent 取数:让大模型通过一个稳定接口访问数据库,配合命名参数控制注入风险。SUDB 也可升级为 MCP Server,供 AI Agent 调用。
  • 内部工具与报表:数据分析、临时统计,直接写 SQL 出结果。
  • 多表只读 + 单表可写:通过数据库账号权限,精细控制每张表的可操作范围。

结语

SUDB 把"数据库操作"抽象为"发送一条 SQL",用一个接口覆盖了增删改查、聚合与元数据查询,并把安全边界交还给数据库账号权限这一可信来源。

文中所有示例都可以直接复制到终端运行——演示环境公开可用,user 表可自由增删改查(请测试后清理数据),其余表以只读为主。如果你想在自己的数据库上启用 SUDB,只需替换接口地址、数据源名称与 API Key,请求结构和行为完全一致。

立即体验:apiSQL 官网 · 在线云平台