From a58275aa51f99203d056fcdf05325451daf062bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E8=AE=A9=E5=AE=87?= Date: Fri, 11 Sep 2026 01:17:21 +0800 Subject: [PATCH] =?UTF-8?q?docs(rules):=20=E8=A1=A5=20ADT=20Data=20Preview?= =?UTF-8?q?=20SQL=20=E6=96=B9=E8=A8=80=E5=AE=9E=E6=B5=8B=E7=BA=A6=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真机侦察(S4T / NW 7.40)确认 data preview freestyle 解析器只接受窄 SQL 子集: - 选择列必须逗号分隔;WHERE 不支持 =,只支持 IN / LIKE - 现状 --where 'F=X' 会 400 并抛未捕获堆栈(非友好报错) 新增:错误速查 3 行 + 方言/元数据表对照小节(DD02T/DD40T/DD04T/DD01T + TADIR); sap-tool-constraints 规则 9 + 自检项 10。references/ 与 .claude/rules/ 已同步。 顺带记录:info 的传输请求恒为 (无法获取)——E071 查询用的 = 在该方言必 400,异常被吞。 --- .claude/rules/error-handling.md | 29 +++++++++++++++++++++++++++ .claude/rules/sap-tool-constraints.md | 16 +++++++++++++++ references/error-handling.md | 29 +++++++++++++++++++++++++++ references/sap-tool-constraints.md | 16 +++++++++++++++ 4 files changed, 90 insertions(+) diff --git a/.claude/rules/error-handling.md b/.claude/rules/error-handling.md index f3025d1..b7c99eb 100644 --- a/.claude/rules/error-handling.md +++ b/.claude/rules/error-handling.md @@ -120,3 +120,32 @@ NW 7.40 的 double-activate 已内置在 sap-cli 中。如果 activate 仍然失 | HTTP 423 (Transport lock) | 对象绑定在传输请求中 | 报告用户,SE09 处理 | | 激活失败仍 inactive | NW 7.40 ADT 限制 | sap-cli 已内置 double-activate,仍失败则报告用户去 SE09 | | `WITH EMPTY KEY` 运行 dump | NW 7.40 不支持 | 修改为 `WITH NON-UNIQUE KEY` 或 `WITH DEFAULT KEY` | +| HTTP 400 (Data Preview) `A Boolean expression was expected in <字段>=` | ADT Data Preview freestyle SQL **不支持 `=` 比较**(实测:`WHERE f='x'`→400,`WHERE f IN ('x')`→200) | 改用 `IN (...)` 或 `LIKE '...'`,不要用 `=` | +| HTTP 400 (Data Preview) `elements in the SELECT LIST list must be separated using commas` | 选择列必须逗号分隔(`SELECT a b` 报错) | 写成 `SELECT a, b FROM t` | +| `info` 的「传输请求」恒为 `(无法获取)` | `_query_transport_request` 用 `=` + 单引号查 E071,在该方言下必然 400(异常被吞,故静默失败) | 改为 `WHERE object IN ('...') AND obj_name IN ('...')` | + +## ADT Data Preview SQL 方言(NW 7.40 实测,2026-09-11) + +用于补 ZMM_BIP 系列等元数据时,本系统 `/sap/bc/adt/datapreview/freestyle` 的 SQL 解析器只接受很窄的子集: + +| 能力 | 实测结果 | +|------|----------| +| `SELECT f1, f2 FROM t`(逗号分隔) | ✅ 200 | +| `WHERE f IN ('a','b')` | ✅ 200 | +| `WHERE f LIKE 'ZMM%'` | ✅ 200 | +| `WHERE f = 'a'` | ❌ 400 `A Boolean expression was expected` | +| `SELECT f1 f2`(无逗号) | ❌ 400 要求逗号分隔 | +| 无 WHERE 全表 | ✅ 200(但行数受行数参数与授权限制) | + +**可用的元数据来源(本机实测)**: + +| 对象类型 | 描述表(键, 语言, 文本) | 开发包来源 | +|----------|--------------------------|------------| +| 结构 / 表 | `DD02T`(`TABNAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='TABL'`) | +| 表类型 | `DD40T`(`TYPENAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='TTYP'`) | +| 数据元素 | `DD04T`(`ROLLNAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='DTEL'`) | +| 域 | `DD01T`(`DOMNAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='DOMA'`) | +| 类 | ADT 已直接提供 | `TADIR`(`OBJECT='CLAS'`) | + +- 描述文本的语言不统一:同一批 ZMM_BIP 结构里有的只有 `DDLANGUAGE='1'`,有的只有 `'E'`;补全时必须按「登录语言 → `E` → `1` → 首行」回退,不能硬取一种。 +- **ZMM_BIP 系列 9 个 DDIC 对象在 `TADIR` 里查不到任何行**(结构与表类型均无注册)→ 无法从系统取得开发包,也意味着未登记对象目录(传输/对象清单角度需注意)。 diff --git a/.claude/rules/sap-tool-constraints.md b/.claude/rules/sap-tool-constraints.md index 53e5255..f6e811d 100644 --- a/.claude/rules/sap-tool-constraints.md +++ b/.claude/rules/sap-tool-constraints.md @@ -120,6 +120,21 @@ python main.py read-table --name ZSAPILOT_OBJ --max-rows 50 - ❌ 把「S4T 演示机通过」表述为「CEM/生产验证通过」 - ❌ 多会话并发操作同一批对象(派下一会话前先确认前一个已退出) +## 🚫 规则 9:read-table 的 `--where` 只能写 `IN` / `LIKE` + +`read-table` 走 ADT Data Preview freestyle 解析器,只接受很窄的 SQL 子集。**用 `=` 会返回 400,并以未捕获异常打印堆栈**(不是友好报错)。 + +| 写法 | 实测结果 | +|------|----------| +| `--where "TABNAME IN ('ZMM_BIP_001_HEADER')"` | ✅ 200 | +| `--where "OBJ_NAME LIKE 'ZMM_BIP%'"` | ✅ 200 | +| `--where "TABNAME='ZMM_BIP_001_HEADER'"` | ❌ 400 `A Boolean expression was expected` | +| `--fields "A,B"`(逗号分隔) | ✅ 200 | +| `--fields "A B"`(空格分隔) | ❌ 400 要求逗号分隔 | + +- 要按多个值过滤,**一次 `IN` 查完**,不要循环单点查。 +- 更多方言细节与元数据表对照见 `error-handling.md`「ADT Data Preview SQL 方言」。 + ## 自检清单 每次执行 SAP 操作前,确认: @@ -133,3 +148,4 @@ python main.py read-table --name ZSAPILOT_OBJ --max-rows 50 7. ✅ 我按「本地改 → 同步 → 语法检查 → 循环至 0 错误 → 激活 → 测试」执行了吗? 8. ✅ 我核实过被调函数/结构的存在性与签名了吗(E04/E05)? 9. ✅ 同一任务只有一个开发者会话在跑吗? +10. ✅ `read-table` 的 `--where` 我用的是 `IN` / `LIKE` 而不是 `=` 吗?`--fields` 是逗号分隔吗? diff --git a/references/error-handling.md b/references/error-handling.md index f3025d1..b7c99eb 100644 --- a/references/error-handling.md +++ b/references/error-handling.md @@ -120,3 +120,32 @@ NW 7.40 的 double-activate 已内置在 sap-cli 中。如果 activate 仍然失 | HTTP 423 (Transport lock) | 对象绑定在传输请求中 | 报告用户,SE09 处理 | | 激活失败仍 inactive | NW 7.40 ADT 限制 | sap-cli 已内置 double-activate,仍失败则报告用户去 SE09 | | `WITH EMPTY KEY` 运行 dump | NW 7.40 不支持 | 修改为 `WITH NON-UNIQUE KEY` 或 `WITH DEFAULT KEY` | +| HTTP 400 (Data Preview) `A Boolean expression was expected in <字段>=` | ADT Data Preview freestyle SQL **不支持 `=` 比较**(实测:`WHERE f='x'`→400,`WHERE f IN ('x')`→200) | 改用 `IN (...)` 或 `LIKE '...'`,不要用 `=` | +| HTTP 400 (Data Preview) `elements in the SELECT LIST list must be separated using commas` | 选择列必须逗号分隔(`SELECT a b` 报错) | 写成 `SELECT a, b FROM t` | +| `info` 的「传输请求」恒为 `(无法获取)` | `_query_transport_request` 用 `=` + 单引号查 E071,在该方言下必然 400(异常被吞,故静默失败) | 改为 `WHERE object IN ('...') AND obj_name IN ('...')` | + +## ADT Data Preview SQL 方言(NW 7.40 实测,2026-09-11) + +用于补 ZMM_BIP 系列等元数据时,本系统 `/sap/bc/adt/datapreview/freestyle` 的 SQL 解析器只接受很窄的子集: + +| 能力 | 实测结果 | +|------|----------| +| `SELECT f1, f2 FROM t`(逗号分隔) | ✅ 200 | +| `WHERE f IN ('a','b')` | ✅ 200 | +| `WHERE f LIKE 'ZMM%'` | ✅ 200 | +| `WHERE f = 'a'` | ❌ 400 `A Boolean expression was expected` | +| `SELECT f1 f2`(无逗号) | ❌ 400 要求逗号分隔 | +| 无 WHERE 全表 | ✅ 200(但行数受行数参数与授权限制) | + +**可用的元数据来源(本机实测)**: + +| 对象类型 | 描述表(键, 语言, 文本) | 开发包来源 | +|----------|--------------------------|------------| +| 结构 / 表 | `DD02T`(`TABNAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='TABL'`) | +| 表类型 | `DD40T`(`TYPENAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='TTYP'`) | +| 数据元素 | `DD04T`(`ROLLNAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='DTEL'`) | +| 域 | `DD01T`(`DOMNAME`/`DDLANGUAGE`/`DDTEXT`) | `TADIR`(`OBJECT='DOMA'`) | +| 类 | ADT 已直接提供 | `TADIR`(`OBJECT='CLAS'`) | + +- 描述文本的语言不统一:同一批 ZMM_BIP 结构里有的只有 `DDLANGUAGE='1'`,有的只有 `'E'`;补全时必须按「登录语言 → `E` → `1` → 首行」回退,不能硬取一种。 +- **ZMM_BIP 系列 9 个 DDIC 对象在 `TADIR` 里查不到任何行**(结构与表类型均无注册)→ 无法从系统取得开发包,也意味着未登记对象目录(传输/对象清单角度需注意)。 diff --git a/references/sap-tool-constraints.md b/references/sap-tool-constraints.md index 53e5255..f6e811d 100644 --- a/references/sap-tool-constraints.md +++ b/references/sap-tool-constraints.md @@ -120,6 +120,21 @@ python main.py read-table --name ZSAPILOT_OBJ --max-rows 50 - ❌ 把「S4T 演示机通过」表述为「CEM/生产验证通过」 - ❌ 多会话并发操作同一批对象(派下一会话前先确认前一个已退出) +## 🚫 规则 9:read-table 的 `--where` 只能写 `IN` / `LIKE` + +`read-table` 走 ADT Data Preview freestyle 解析器,只接受很窄的 SQL 子集。**用 `=` 会返回 400,并以未捕获异常打印堆栈**(不是友好报错)。 + +| 写法 | 实测结果 | +|------|----------| +| `--where "TABNAME IN ('ZMM_BIP_001_HEADER')"` | ✅ 200 | +| `--where "OBJ_NAME LIKE 'ZMM_BIP%'"` | ✅ 200 | +| `--where "TABNAME='ZMM_BIP_001_HEADER'"` | ❌ 400 `A Boolean expression was expected` | +| `--fields "A,B"`(逗号分隔) | ✅ 200 | +| `--fields "A B"`(空格分隔) | ❌ 400 要求逗号分隔 | + +- 要按多个值过滤,**一次 `IN` 查完**,不要循环单点查。 +- 更多方言细节与元数据表对照见 `error-handling.md`「ADT Data Preview SQL 方言」。 + ## 自检清单 每次执行 SAP 操作前,确认: @@ -133,3 +148,4 @@ python main.py read-table --name ZSAPILOT_OBJ --max-rows 50 7. ✅ 我按「本地改 → 同步 → 语法检查 → 循环至 0 错误 → 激活 → 测试」执行了吗? 8. ✅ 我核实过被调函数/结构的存在性与签名了吗(E04/E05)? 9. ✅ 同一任务只有一个开发者会话在跑吗? +10. ✅ `read-table` 的 `--where` 我用的是 `IN` / `LIKE` 而不是 `=` 吗?`--fields` 是逗号分隔吗?