497 lines
13 KiB
Markdown
497 lines
13 KiB
Markdown
# API 文档 - SOQL 查询功能 (004-08)
|
||
|
||
## 元数据
|
||
- **需求编号**: 004-08
|
||
- **需求名称**: SOQL 查询功能
|
||
- **版本号**: v1.0.0
|
||
- **创建时间**: 2026-02-06
|
||
- **创建人**: AI Assistant
|
||
- **模块**: datai-salesforce-tooling
|
||
|
||
---
|
||
|
||
## API 概述
|
||
|
||
SOQL 查询功能 API 提供了一组 RESTful 接口,用于执行 Salesforce Tooling API 的 SOQL 查询操作。支持执行任意 SOQL 查询、获取更多查询结果(queryMore)、查询所有结果(自动处理分页)、使用 SoqlBuilder 构建和执行查询,以及查询操作日志管理。
|
||
|
||
### 核心功能
|
||
- 执行 SOQL 查询,返回查询结果和 queryLocator
|
||
- 使用 queryLocator 获取更多查询结果
|
||
- 自动分页查询所有结果
|
||
- 使用 SoqlBuilder 构建和执行查询
|
||
- 查询操作日志管理
|
||
|
||
### 技术架构
|
||
- **Controller**: ToolingSoqlQueryController
|
||
- **Service**: IToolingSoqlQueryService / ToolingSoqlQueryServiceImpl
|
||
- **Connection**: ToolingConnectionFactory (复用 004-01)
|
||
- **Builder**: SoqlBuilder (复用现有工具类)
|
||
|
||
---
|
||
|
||
## 接口列表
|
||
|
||
### 接口 1:执行 SOQL 查询
|
||
|
||
**功能描述**: 执行任意 SOQL 查询语句,返回查询结果和 queryLocator。支持所有 Tooling API 对象的查询。
|
||
|
||
**请求方式**: POST
|
||
|
||
**请求路径**: `/salesforce/tooling/soql/query`
|
||
|
||
**权限要求**: `tooling:soql:query`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| queryString | String | 是 | SOQL 查询语句,例如 "SELECT Id, Name FROM ApexClass LIMIT 100" |
|
||
| source | String | 否 | 数据源标识,默认 "source" |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"queryString": "SELECT Id, Name, Body FROM ApexClass LIMIT 100",
|
||
"source": "source"
|
||
}
|
||
```
|
||
|
||
**响应参数**:
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果数据 |
|
||
| data.success | Boolean | 查询是否成功 |
|
||
| data.errorCode | String | 错误码(失败时返回) |
|
||
| data.errorMessage | String | 错误信息(失败时返回) |
|
||
| data.queryLocator | String | 查询定位器,用于获取更多结果 |
|
||
| data.records | Array | 查询结果记录列表 |
|
||
| data.totalSize | Integer | 总记录数 |
|
||
| data.done | Boolean | 是否已获取所有结果 |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"data": {
|
||
"success": true,
|
||
"queryLocator": "01gXXXXXXXXXXXXXXX",
|
||
"records": [
|
||
{
|
||
"Id": "01pXXXXXXXXXXXXXXX",
|
||
"Name": "MyApexClass",
|
||
"Body": "public class MyApexClass { ... }"
|
||
}
|
||
],
|
||
"totalSize": 1,
|
||
"done": false
|
||
}
|
||
}
|
||
```
|
||
|
||
**失败响应示例**:
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "查询失败",
|
||
"data": {
|
||
"success": false,
|
||
"errorCode": "TOOLING_SOQL_002",
|
||
"errorMessage": "查询失败:无效的查询语句"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 接口 2:获取更多查询结果
|
||
|
||
**功能描述**: 使用 queryLocator 获取更多查询结果(queryMore)。当一次查询无法返回所有结果时,使用此接口获取后续结果。
|
||
|
||
**请求方式**: POST
|
||
|
||
**请求路径**: `/salesforce/tooling/soql/queryMore`
|
||
|
||
**权限要求**: `tooling:soql:query`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| queryLocator | String | 是 | 查询定位器,从上一次查询结果中获取 |
|
||
| source | String | 否 | 数据源标识,默认 "source" |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"queryLocator": "01gXXXXXXXXXXXXXXX",
|
||
"source": "source"
|
||
}
|
||
```
|
||
|
||
**响应参数**:
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果数据 |
|
||
| data.success | Boolean | 查询是否成功 |
|
||
| data.errorCode | String | 错误码(失败时返回) |
|
||
| data.errorMessage | String | 错误信息(失败时返回) |
|
||
| data.queryLocator | String | 查询定位器,用于获取更多结果 |
|
||
| data.records | Array | 查询结果记录列表 |
|
||
| data.totalSize | Integer | 总记录数 |
|
||
| data.done | Boolean | 是否已获取所有结果 |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"data": {
|
||
"success": true,
|
||
"queryLocator": null,
|
||
"records": [
|
||
{
|
||
"Id": "01pXXXXXXXXXXXXXXX",
|
||
"Name": "AnotherApexClass"
|
||
}
|
||
],
|
||
"totalSize": 1,
|
||
"done": true
|
||
}
|
||
}
|
||
```
|
||
|
||
**失败响应示例**:
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "查询定位器无效",
|
||
"data": {
|
||
"success": false,
|
||
"errorCode": "TOOLING_SOQL_005",
|
||
"errorMessage": "查询定位器无效或已过期"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 接口 3:查询所有结果
|
||
|
||
**功能描述**: 自动分页查询所有结果,合并返回完整数据列表。适用于需要获取所有记录的场景,自动处理分页逻辑。
|
||
|
||
**注意**: Salesforce 限制最多返回 50000 条记录,超过限制将返回错误。
|
||
|
||
**请求方式**: POST
|
||
|
||
**请求路径**: `/salesforce/tooling/soql/queryAll`
|
||
|
||
**权限要求**: `tooling:soql:query`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| queryString | String | 是 | SOQL 查询语句 |
|
||
| source | String | 否 | 数据源标识,默认 "source" |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"queryString": "SELECT Id, Name FROM ApexClass",
|
||
"source": "source"
|
||
}
|
||
```
|
||
|
||
**响应参数**:
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果数据 |
|
||
| data.success | Boolean | 查询是否成功 |
|
||
| data.errorCode | String | 错误码(失败时返回) |
|
||
| data.errorMessage | String | 错误信息(失败时返回) |
|
||
| data.records | Array | 所有查询结果记录列表 |
|
||
| data.totalSize | Integer | 总记录数 |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"data": {
|
||
"success": true,
|
||
"records": [
|
||
{
|
||
"Id": "01pXXXXXXXXXXXXXXX",
|
||
"Name": "Class1"
|
||
},
|
||
{
|
||
"Id": "01pYYYYYYYYYYYYYYY",
|
||
"Name": "Class2"
|
||
}
|
||
],
|
||
"totalSize": 2
|
||
}
|
||
}
|
||
```
|
||
|
||
**失败响应示例** (超过 50000 条记录限制):
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "查询结果超出限制",
|
||
"data": {
|
||
"success": false,
|
||
"errorCode": "TOOLING_SOQL_006",
|
||
"errorMessage": "查询结果超出 50000 条记录限制,请使用分页查询"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 接口 4:使用 SoqlBuilder 执行查询
|
||
|
||
**功能描述**: 使用 SoqlBuilder 构建和执行查询。适用于需要动态构建查询条件的场景,提供更灵活的查询方式。
|
||
|
||
**请求方式**: POST
|
||
|
||
**请求路径**: `/salesforce/tooling/soql/queryWithBuilder`
|
||
|
||
**权限要求**: `tooling:soql:query`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| select | String | 是 | SELECT 子句,例如 "Id, Name, Body" |
|
||
| from | String | 是 | FROM 子句,例如 "ApexClass" |
|
||
| where | String | 否 | WHERE 子句,例如 "Name LIKE 'My%'" |
|
||
| orderBy | String | 否 | ORDER BY 子句,例如 "Name ASC" |
|
||
| limit | Integer | 否 | LIMIT 子句,例如 100 |
|
||
| source | String | 否 | 数据源标识,默认 "source" |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"select": "Id, Name, Body",
|
||
"from": "ApexClass",
|
||
"where": "Name LIKE 'My%'",
|
||
"orderBy": "Name ASC",
|
||
"limit": 100,
|
||
"source": "source"
|
||
}
|
||
```
|
||
|
||
**响应参数**:
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果数据 |
|
||
| data.success | Boolean | 查询是否成功 |
|
||
| data.errorCode | String | 错误码(失败时返回) |
|
||
| data.errorMessage | String | 错误信息(失败时返回) |
|
||
| data.queryLocator | String | 查询定位器 |
|
||
| data.records | Array | 查询结果记录列表 |
|
||
| data.totalSize | Integer | 总记录数 |
|
||
| data.done | Boolean | 是否已获取所有结果 |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"data": {
|
||
"success": true,
|
||
"queryLocator": null,
|
||
"records": [
|
||
{
|
||
"Id": "01pXXXXXXXXXXXXXXX",
|
||
"Name": "MyApexClass",
|
||
"Body": "public class MyApexClass { ... }"
|
||
}
|
||
],
|
||
"totalSize": 1,
|
||
"done": true
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 接口 5:获取查询日志列表
|
||
|
||
**功能描述**: 获取 SOQL 查询操作日志列表,支持分页查询。用于审计和监控查询操作。
|
||
|
||
**请求方式**: GET
|
||
|
||
**请求路径**: `/salesforce/tooling/soql/logs`
|
||
|
||
**权限要求**: `tooling:soql:log:query`
|
||
|
||
**请求参数** (Query 参数):
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| pageNum | Integer | 否 | 页码,默认 1 |
|
||
| pageSize | Integer | 否 | 每页大小,默认 10 |
|
||
| queryType | String | 否 | 查询类型筛选,例如 "QUERY", "QUERY_MORE", "QUERY_ALL" |
|
||
| success | Boolean | 否 | 是否成功筛选 |
|
||
| startTime | String | 否 | 开始时间,格式:yyyy-MM-dd HH:mm:ss |
|
||
| endTime | String | 否 | 结束时间,格式:yyyy-MM-dd HH:mm:ss |
|
||
|
||
**请求示例**:
|
||
```
|
||
GET /salesforce/tooling/soql/logs?pageNum=1&pageSize=10&queryType=QUERY&success=true
|
||
```
|
||
|
||
**响应参数**:
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 分页数据 |
|
||
| data.total | Long | 总记录数 |
|
||
| data.rows | Array | 日志记录列表 |
|
||
| data.rows[].id | Long | 日志 ID |
|
||
| data.rows[].queryString | String | 查询字符串 |
|
||
| data.rows[].queryType | String | 查询类型 |
|
||
| data.rows[].executionTimeMs | Long | 执行时间(毫秒) |
|
||
| data.rows[].resultCount | Integer | 结果数量 |
|
||
| data.rows[].success | Boolean | 是否成功 |
|
||
| data.rows[].errorMessage | String | 错误信息 |
|
||
| data.rows[].createTime | String | 创建时间 |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"data": {
|
||
"total": 100,
|
||
"rows": [
|
||
{
|
||
"id": 1,
|
||
"queryString": "SELECT Id, Name FROM ApexClass LIMIT 100",
|
||
"queryType": "QUERY",
|
||
"executionTimeMs": 150,
|
||
"resultCount": 100,
|
||
"success": true,
|
||
"errorMessage": null,
|
||
"createTime": "2026-02-06 10:30:00"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误码
|
||
|
||
| 错误码 | 错误信息 | 使用场景 | HTTP 状态码 |
|
||
|-------|---------|---------|------------|
|
||
| TOOLING_SOQL_001 | Session 无效或已过期 | 用户未登录或 Session 过期 | 401 |
|
||
| TOOLING_SOQL_002 | 查询失败 | SOQL 查询执行失败(语法错误、对象不存在等) | 500 |
|
||
| TOOLING_SOQL_003 | 权限不足 | 用户没有执行查询的权限 | 403 |
|
||
| TOOLING_SOQL_004 | 用户未登录 | 用户未登录 | 401 |
|
||
| TOOLING_SOQL_005 | 查询定位器无效 | queryLocator 无效或已过期 | 400 |
|
||
| TOOLING_SOQL_006 | 查询结果超出限制 | 查询结果超过 50000 条记录限制 | 400 |
|
||
|
||
---
|
||
|
||
## SOQL 查询限制
|
||
|
||
### Salesforce SOQL 限制
|
||
- **最大返回记录数**: 50000 条
|
||
- **OFFSET 上限**: 2000,且必须与 LIMIT 一起使用
|
||
- **不支持 SELECT ***: 必须明确指定字段或使用 FIELDS()
|
||
- **不支持 BETWEEN**: 请使用 >= 和 <= 组合代替
|
||
- **不支持 JOIN**: 使用关系查询(Relationship Queries)
|
||
- **不支持 UNION**: 无法合并两个不相关的结果集
|
||
|
||
### 支持的运算符
|
||
`=`, `!=`, `>`, `>=`, `<`, `<=`, `LIKE`, `IN`, `NOT IN`, `= NULL`, `!= NULL`
|
||
|
||
### 支持的子句
|
||
`WHERE`, `GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`, `OFFSET`
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
### 示例 1:基本查询
|
||
```bash
|
||
curl -X POST "http://localhost:8080/salesforce/tooling/soql/query" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer {token}" \
|
||
-d '{
|
||
"queryString": "SELECT Id, Name FROM ApexClass LIMIT 10"
|
||
}'
|
||
```
|
||
|
||
### 示例 2:带条件的查询
|
||
```bash
|
||
curl -X POST "http://localhost:8080/salesforce/tooling/soql/query" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer {token}" \
|
||
-d '{
|
||
"queryString": "SELECT Id, Name, Body FROM ApexClass WHERE Name LIKE \"My%\" ORDER BY Name ASC LIMIT 50"
|
||
}'
|
||
```
|
||
|
||
### 示例 3:使用 SoqlBuilder
|
||
```bash
|
||
curl -X POST "http://localhost:8080/salesforce/tooling/soql/queryWithBuilder" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer {token}" \
|
||
-d '{
|
||
"select": "Id, Name, Body",
|
||
"from": "ApexClass",
|
||
"where": "Name LIKE \"My%\"",
|
||
"orderBy": "Name ASC",
|
||
"limit": 50
|
||
}'
|
||
```
|
||
|
||
### 示例 4:分页查询所有结果
|
||
```bash
|
||
curl -X POST "http://localhost:8080/salesforce/tooling/soql/queryAll" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer {token}" \
|
||
-d '{
|
||
"queryString": "SELECT Id, Name FROM ApexTrigger"
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- [需求文档](../requirements/sub/2026-01-28-004-08-SOQL查询功能.md)
|
||
- [设计文档](../design/2026-02-03-004-08-SOQL查询功能-设计.md)
|
||
- [决策记录](../decisions/2026-02-03-004-08-ADR-SOQL查询功能技术选型.md)
|
||
- [变更日志](../changelog/2026-02-06-004-08-changelog.md)
|
||
- [复盘文档](../retros/2026-02-06-004-08-retro.md)
|
||
|
||
---
|
||
|
||
## 版本历史
|
||
|
||
### v1.0.0 (2026-02-06)
|
||
- 初始版本
|
||
- 实现 5 个 REST API 接口
|
||
- 支持执行 SOQL 查询、queryMore、queryAll、SoqlBuilder 查询、日志管理
|