datai/datai-scenes/datai-scene-salesforce/docs/api-docs/2026-02-06-004-08-api.md

497 lines
13 KiB
Markdown
Raw Normal View History

# 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 查询、日志管理