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

497 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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