Files
oracle-jump-query-public/references/legacy-skill-v1.5.8.md
T

26 KiB
Raw Blame History

name, description
name description
oracle-jump-query Oracle 跳板查询技能。通过中转服务查询远程 Oracle 数据库的元数据(存储过程源码、依赖、表结构、触发器、直接查表),连接数据库为只读,禁止任何写操作。当用户需要分析 Oracle 存储过程、查找依赖表、查询表结构、查看业务逻辑时触发。

Oracle 跳板查询

版本:v1.5.8 · 更新日志

概述

通过中转服务(Transit Server)查询远程 Oracle 数据库服务器的存储过程元数据,无需开放数据库端口。

架构

AI Skill → HTTP → Transit Server (:6357) → WebSocket → Agent → Oracle

前置条件

  1. 中转服务已部署并运行(IP: 47.97.171.89, Port: 6357)
  2. Agent 已部署到数据库服务器并连接中转服务
  3. 本地已安装 Python 依赖:pip install requests

配置

配置文件位于技能目录下:D:\work\恒诺\长期支持\跳板查询\demo\ai-skill\config.json

{
    "transit_url": "http://47.97.171.89:6357",
    "server_id": "server-001",
    "access_token": "",
    "expires_at": ""
}

使用查询命令前先登录中转机:

python oracle_skill.py login <secretKey> [clientCode]

登录成功后只保存中转机签发的 access_token 和过期时间,不保存 BOS secretKey。clientCode 是客户服务器编号,非必填;不传时中转机会默认选择 BOS 返回的第一个可用 client。

同一个 secretKey 同时只允许一个设备在线。另一台设备重新登录后,当前设备的 token 会立即失效,需要重新执行 login <secretKey> [clientCode]。

调用方式

使用 scripts/oracle_skill.py 脚本:

python scripts/oracle_skill.py <command> [args]

可用命令

命令 说明 示例
analyze <schema> <proc> 完整分析存储过程 python oracle_skill.py analyze BOS M_RETAIL_SUBMIT
list <schema> 列出 schema 下所有存储过程 python oracle_skill.py list BOS
source <schema> <proc> 获取存储过程源码 python oracle_skill.py source BOS M_RETAIL_SUBMIT
deps <schema> <proc> 获取依赖(表/存储过程) python oracle_skill.py deps BOS M_RETAIL_SUBMIT
tables <schema> <proc> 获取相关表结构 python oracle_skill.py tables BOS M_RETAIL_SUBMIT
describe <schema> <table> 查询表结构(列、索引、行数) python oracle_skill.py describe bosnds3 xcx_so
discover [schema] [domain] 发现核心业务域(NL2SQL前置) python oracle_skill.py discover BOSNDS3 RETAIL
nl2sql [schema] [domain] 生成 NL2SQL Schema 字典 python oracle_skill.py nl2sql BOSNDS3 RETAIL
query <SQL> 执行 SELECT 查询,生产表必须带过滤条件和行数限制 python oracle_skill.py query "SELECT * FROM M_RETAIL WHERE BILLDATE=20260501 AND ROWNUM<=20"
perm <userId> <tableId> [col] 查询用户数据权限 python oracle_skill.py perm 940 12983
qperm <userId> <tableId> <SQL> 带权限过滤的查询 python oracle_skill.py qperm 940 12983 "SELECT * FROM M_OTHER_INOUT"
login <secretKey> [clientCode] 登录中转机 + 选择客户服务器,clientCode 非必填 python oracle_skill.py login mykey HENLO
logout 登出中转机并清除本地 token python oracle_skill.py logout
status 查看中转机登录状态 + 当前 client python oracle_skill.py status
switch <clientCode> 切换 client python oracle_skill.py switch OTHER_CLIENT
clients 获取当前用户可访问 client 及在线状态 python oracle_skill.py clients
servers 列出在线 Agent python oracle_skill.py servers
health 检查中转服务状态 python oracle_skill.py health
tablespace / tablespaces 查询表空间使用情况 python oracle_skill.py tablespace

交互模式

不传参数直接运行,进入交互模式:

python scripts/oracle_skill.py

生产查询限制

直接查询业务表时,必须带明确过滤条件,不要直接查询整表。生产环境数据量很大,SELECT * FROM <table> 这类无条件查询可能返回大量数据、拖慢 Agent 或影响数据库。

生成或执行 query / qperm SQL 时遵守:

  • 必须有 WHERE 条件,优先使用日期、单号、门店、客户、状态、主键等业务过滤条件。
  • 必须加行数限制,例如 ROWNUM <= 20;需要分页时分批查询。
  • 不要为了“先看看数据”执行无条件整表查询。
  • 统计查询也要限定业务范围,例如日期区间、单据状态、门店范围。
  • 如果用户没有给出过滤条件,先追问条件,或先用 describe / AD_COLUMN / AD_TABLE 查询结构和字段含义。

推荐示例:

SELECT *
FROM M_RETAIL
WHERE BILLDATE = 20260501
  AND STATUS = '2'
  AND ROWNUM <= 20

避免示例:

SELECT * FROM M_RETAIL

常用业务对象说明

当用户使用商品、款号、条码、SKU、库存等业务词时,默认按以下对象理解:

  • “商品”“款号”通常指 M_PRODUCT 表。
  • “条码”“SKU”通常指 M_PRODUCT_ALIAS 表。
  • 查询条码/SKU 时,首查 M_PRODUCT_ALIAS.NO 字段。
  • 款号和条码是一对多关系:一个 M_PRODUCT 可以对应多条 M_PRODUCT_ALIAS。
  • 如果涉及库存查询,通常查询 V_FA_STORAGE 视图。
  • V_FA_STORAGE 数据量很大,必须同时带店仓条件和款号/条码条件,不允许只查整张库存视图。

库存查询过滤规则:

  • 店仓条件应优先使用门店、仓库、店仓 ID 或店仓编码等字段,先通过 describe 或 AD_COLUMN 确认实际字段名。
  • 款号条件走 M_PRODUCT;条码/SKU 条件走 M_PRODUCT_ALIAS。
  • 通过条码查库存时,应先用 M_PRODUCT_ALIAS.NO 找到对应商品,再关联或过滤 V_FA_STORAGE。
  • 必须加 ROWNUM 或分页限制;如果用户没有提供店仓或款号/条码,先追问,不要直接查询库存视图。

示例思路:

-- 伪示例:实际字段名需先 describe / AD_COLUMN 确认
SELECT *
FROM V_FA_STORAGE s
WHERE s.C_STORE_ID = :store_id
  AND s.M_PRODUCT_ID = :product_id
  AND ROWNUM <= 20

分析报告内容

analyze 命令返回完整分析报告,包含:

  • 源码:完整 PL/SQL 代码
  • 依赖:涉及的表、视图、嵌套存储过程/函数
  • 表结构:相关表的列信息(列名、类型、长度、可空)
  • 触发器:相关表上的触发器列表

直接 HTTP 调用

不通过脚本,直接调用中转服务 API:

分析存储过程

curl -X POST http://47.97.171.89:6357/api/query \
  -H "Content-Type: application/json" \
  -d '{
    "server_id": "server-001",
    "action": "analyze_procedure",
    "schema": "BOS",
    "name": "M_RETAIL_SUBMIT",
    "timeout": 60
  }'

查询表结构

curl -X POST http://47.97.171.89:6357/api/query \
  -H "Content-Type: application/json" \
  -d '{
    "server_id": "server-001",
    "action": "describe_table",
    "schema": "bosnds3",
    "name": "xcx_so",
    "timeout": 30
  }'

action 类型

action 说明
analyze_procedure 完整分析
list_procedures 列出存储过程
get_source 源码
get_dependencies 依赖
get_tables 表结构(通过存储过程依赖)
describe_table 查询表结构(列、索引、行数、注释)
execute_query 执行 SELECT 查询(只读)—— 表空间查询也复用此 action
schema_discovery 发现核心业务域
generate_nl2sql_schema 生成 NL2SQL Schema 字典

数据字典(AD_TABLE / AD_COLUMN / AD_REFBYTABLE)

通用查询规则

处理 BOS 业务单据(如零售单、采购单、调拨单、销售单等)时,必须遵循以下查询路径:

1. 术语 → 表名(AD_TABLE)

遇到不懂的业务术语(如"零售单提交"、"采购入库"),先查 AD_TABLE:

SELECT ID, NAME, TABLENAME, DESCRIPTION, PROC_SUBMIT
FROM AD_TABLE
WHERE NAME LIKE '%关键词%' OR DESCRIPTION LIKE '%关键词%'
  • NAME:表名(英文,如 M_RETAIL)
  • DESCRIPTION:业务说明(中文,如"零售单")
  • PROC_SUBMIT:该单据的提交存储过程名称(非空即代表该表有提交逻辑)

2. 字段含义(AD_COLUMN)

不理解某个字段的业务含义时,查 AD_COLUMN:

SELECT DBNAME, NAME, DESCRIPTION, COLTYPE
FROM AD_COLUMN
WHERE AD_TABLE_ID = <AD_TABLE.ID>
ORDER BY ORDERNO

3. 主表 → 明细表(AD_REFBYTABLE)

对于单据类表,其明细表、付款表等子表必须通过 AD_REFBYTABLE 查找,不要靠猜测命名规则:

SELECT t1.NAME AS MAIN_TABLE,
       t2.NAME AS DETAIL_TABLE,
       c.DBNAME AS REF_COLUMN,
       r.ASSOCTYPE
FROM AD_REFBYTABLE r
LEFT JOIN AD_TABLE t1 ON r.AD_TABLE_ID = t1.ID
LEFT JOIN AD_TABLE t2 ON r.AD_REFBY_TABLE_ID = t2.ID
LEFT JOIN AD_COLUMN c ON r.AD_REFBY_COLUMN_ID = c.ID
WHERE t1.NAME = '<AD_TABLE.NAME>'
  • ASSOCTYPE:"n"=一对多明细,"1"=强关联/嵌入
  • 得到明细表名后,再通过 AD_COLUMN 查看各明细表的字段含义

核心表说明

表 说明
AD_TABLE 所有业务表的元数据注册表,每条记录对应一张业务表
AD_COLUMN 所有业务字段的元数据注册表,含字段名(DBNAME)、显示名(NAME)、描述(DESCRIPTION)、类型(COLTYPE)等
AD_REFBYTABLE 主表与明细表的关联关系,记录主表→明细表的外键引用

AD_REFBYTABLE 关联字段

字段 说明
AD_TABLE_ID 主表ID → 关联 AD_TABLE.ID
AD_REFBY_TABLE_ID 明细表ID → 关联 AD_TABLE.ID
AD_REFBY_COLUMN_ID 明细表中的外键列ID → 关联 AD_COLUMN.ID,通过 AD_COLUMN.DBNAME 获取实际列名
ASSOCTYPE 关联类型("1"=强关联/嵌入, "n"=一对多明细)

查询主表→明细表关系的 SQL 模板

SELECT t1.NAME AS MAIN_TABLE,
       t2.NAME AS DETAIL_TABLE,
       c.DBNAME AS REF_COLUMN,
       r.ASSOCTYPE
FROM AD_REFBYTABLE r
LEFT JOIN AD_TABLE t1 ON r.AD_TABLE_ID = t1.ID
LEFT JOIN AD_TABLE t2 ON r.AD_REFBY_TABLE_ID = t2.ID
LEFT JOIN AD_COLUMN c ON r.AD_REFBY_COLUMN_ID = c.ID
WHERE t1.NAME = 'M_RETAIL'

示例:M_RETAIL 的明细表

主表 明细表 外键列 关联类型
M_RETAIL M_RETAILITEM M_RETAIL_ID n
M_RETAIL M_RETAILPAYITEM M_RETAIL_ID n
M_RETAIL M_RETAIL_PRO_ITEM M_RETAIL_ID n
M_RETAIL M_RETAIL_RATEITEM M_RETAIL_ID n
M_RETAIL M_RETAIL_DISITEM M_RETAIL_ID n
M_RETAIL M_RETAIL_VOUCHERSITEM M_RETAIL_ID n
M_RETAIL M_RETAIL_BATCHITEM M_RETAIL_ID n

查询字段描述的 SQL 模板

SELECT DBNAME, NAME, DESCRIPTION, COLTYPE
FROM AD_COLUMN
WHERE AD_TABLE_ID = (SELECT ID FROM AD_TABLE WHERE NAME = 'M_RETAILITEM')
ORDER BY ORDERNO

BOS 系统地图分析(AD_TABLE_TEXT 经验)

BOSNDS3.AD_TABLE_TEXT 是 BOS 内部的表配置导出脚本生成器。分析该过程可以反推出 BOS 元数据体系:菜单、模块、业务表、字段、主子表、按钮动作、提交过程、权限目录和报表模板主要由数据字典表驱动。

当用户要求分析“BOS 系统菜单 / 模块目录 / 表结构地图 / 某个业务模块结构”时,优先按下面的元数据链路整理,不要只看物理表:

AD_SUBSYSTEM
  -> AD_TABLECATEGORY
  -> AD_ACCORDION
  -> AD_TABLE
  -> AD_COLUMN
  -> AD_REFBYTABLE
  -> AD_ACTION
  -> DIRECTORY
  -> AD_CXTAB / AD_CXTAB_JPARA / AD_CXTAB_DIMENSION / AD_CXTAB_FACT

核心含义:

  • AD_SUBSYSTEM:子系统。
  • AD_TABLECATEGORY:表类别 / 模块分类。
  • AD_ACCORDION:折叠菜单 / 菜单分组。
  • AD_TABLE:业务表注册表,含 DESCRIPTION、PROC_SUBMIT、DIRECTORY_ID、AD_TABLECATEGORY_ID、AD_ACCORDION_ID 等。
  • AD_COLUMN:字段元数据,含字段名、显示名、业务描述、控件类型、引用列、默认值、限定值组等。
  • AD_REFBYTABLE:主表到明细表、子表的关系。
  • AD_ACTION:表动作、按钮、URL、存储过程脚本入口。
  • DIRECTORY:数据权限目录挂载点。
  • AD_CXTAB 相关表:公开查询 / 报表模板及其参数、维度、指标。

常用系统地图 SQL:

SELECT ss.NAME AS SUBSYSTEM,
       tc.NAME AS TABLE_CATEGORY,
       ac.NAME AS ACCORDION,
       t.ID AS AD_TABLE_ID,
       t.NAME AS TABLE_NAME,
       t.DESCRIPTION,
       t.PROC_SUBMIT,
       d.NAME AS DIRECTORY_NAME
FROM AD_TABLE t
LEFT JOIN AD_TABLECATEGORY tc ON tc.ID = t.AD_TABLECATEGORY_ID
LEFT JOIN AD_SUBSYSTEM ss ON ss.ID = tc.AD_SUBSYSTEM_ID
LEFT JOIN AD_ACCORDION ac ON ac.ID = t.AD_ACCORDION_ID
LEFT JOIN DIRECTORY d ON d.ID = t.DIRECTORY_ID
WHERE t.NAME LIKE '%关键词%' OR t.DESCRIPTION LIKE '%关键词%'
ORDER BY ss.NAME, tc.ORDERNO, ac.ORDERNO, t.ORDERNO, t.NAME

分析单个业务表时,至少同时检查:

  • AD_TABLE:表归属、提交过程、权限目录。
  • AD_COLUMN:字段业务含义和值域。
  • AD_REFBYTABLE:明细表和外键列。
  • AD_ACTION:按钮和动作脚本。
  • ALL_TRIGGERS / USER_OBJECTS:触发器、同名前缀过程或函数。

注意:这套元数据能还原 BOS 业务结构,不等于完整物理数据库模型。复杂过程内部逻辑、动态 SQL、触发器副作用和前端特殊页面仍需要结合源码继续分析。

表空间查询

查询 Oracle 表空间使用情况。

自动降级策略

脚本按优先级尝试5 种方式,无需人工切换:

优先级 方式 数据来源 条件 输出字段
1️⃣ 直接 DBA 查询 DBA_DATA_FILES + DBA_FREE_SPACE 用户有 SELECT_CATALOG_ROLE 全部 8 个字段
2️⃣ DBA 专用函数 sys.get_tablespace_usage()(返回 SYS_REFCURSOR) DBA 已执行 CREATE FUNCTION + GRANT 全部 5 个字段(自动解析)
3️⃣ DBA 授权 VIEW(无前缀) HENLO_TS_USAGE 视图 DBA 已执行授权 SQL 全部 8 个字段
4️⃣ DBA 授权 VIEW(sys.前缀) SYS.HENLO_TS_USAGE 视图 DBA 以 SYS 身份创建时自动处理 全部 8 个字段
5️⃣ 用户视图 USER_FREE_SPACE 始终可用 仅表空间名称 + 剩余MB

经验:DBA 以 SYS 身份登录创建的 VIEW 会归属到 SYS schema,需用 sys.HENLO_TS_USAGE 查询。脚本会自动先试无前缀、再试 sys. 前缀。

给 DBA 的授权 SQL

如果当前用户缺少系统视图权限,脚本会自动输出以下 SQL。将其交给 DBA 在 Oracle 中执行一次:

CREATE OR REPLACE VIEW SYS.HENLO_TS_USAGE AS
SELECT
    df.tablespace_name AS "表空间名称",
    ROUND(df.total_bytes / 1048576, 1) AS "总大小MB",
    ROUND((df.total_bytes - NVL(fs.free_bytes, 0)) / 1048576, 1) AS "已用MB",
    ROUND(NVL(fs.free_bytes, 0) / 1048576, 1) AS "剩余MB",
    ROUND((df.total_bytes - NVL(fs.free_bytes, 0)) / df.total_bytes * 100, 1) AS "使用率%",
    df.autoextensible AS "自动拓展",
    ROUND(df.max_bytes / 1048576, 1) AS "最大可拓展MB",
    ROUND((df.total_bytes - NVL(fs.free_bytes, 0)) / NULLIF(df.max_bytes, 0) * 100, 1) AS "最大使用率%"
FROM (
    SELECT
        tablespace_name,
        SUM(bytes) AS total_bytes,
        SUM(CASE WHEN autoextensible = 'YES' THEN maxbytes ELSE bytes END) AS max_bytes,
        MAX(CASE WHEN autoextensible = 'YES' THEN 'YES' ELSE 'NO' END) AS autoextensible
    FROM dba_data_files
    GROUP BY tablespace_name
) df
LEFT JOIN (
    SELECT tablespace_name, SUM(bytes) AS free_bytes
    FROM dba_free_space
    GROUP BY tablespace_name
) fs ON df.tablespace_name = fs.tablespace_name
ORDER BY 6 DESC;

GRANT SELECT ON SYS.HENLO_TS_USAGE TO bosnds3;

原理:Oracle 视图默认使用定义者权限(DEFINER),以视图创建者的 DBA 身份执行,普通用户仅需视图的 SELECT 权限。这比授予 SELECT_CATALOG_ROLE 更安全——只暴露这一个视图的数据。

DBA 执行授权后,再次运行 tablespace 命令即可自动使用完整查询。

输出字段

字段 说明
表空间名称 表空间名称
总大小MB 当前所有数据文件总大小
已用MB 已使用的空间
剩余MB 剩余可用空间
使用率% 已用 / 总大小 × 100%
自动拓展 YES=自动扩展,NO=不自动扩展
最大可拓展MB 开启自动扩展后的最大可达大小
最大使用率% 已用 / 最大可拓展 × 100%(参考阈值 5%)

触发语法

用户可以说:

  • 「帮我查询下表空间」
  • 「查看表空间使用情况」
  • 「表空间是否够用」
python oracle_skill.py tablespace
# 或
python oracle_skill.py tablespaces

阈值规则

使用率 状态 建议
< 80% ✅ 正常 无需处理
80~95% 🔶 关注 评估未来增长,制定扩容计划
≥ 95% ⚠️ 紧急 尽快扩容或清理空间!

智能告警规则:脚本逐行解析表空间数据,自动判断衡量指标。 若表空间已开启自动扩展(自动拓展=YES),按 最大使用率% 判断(已用/最大可拓展); 若未开启(NO),按当前 使用率% 判断(已用/当前总大小)。

这让告警更准确。例如:SYSTEM 使用率 99.4% 但最大使用率仅 3.7%,说明只是当前数据文件写满了,自动扩展后即释放空间,并非真正的存储瓶颈。

使用场景

  1. 查主表的明细表:通过 AD_REFBYTABLE 找到主表关联的所有明细表及外键列
  2. 查字段含义:通过 AD_COLUMN 的 DESCRIPTION 字段了解业务含义
  3. 构建 JOIN 查询:根据外键列名自动拼接主表→明细表的 JOIN 条件
  4. 理解业务模型:通过表间关系理解业务单据结构(如零售单→零售明细→支付明细)

4. 统计数据场景的过滤条件

在 BOS 系统中,进行统计数据查询时,必须遵循以下业务规则:

业务单据通用过滤条件:

  • ISACTIVE = 'Y':单据有效(Y=可用,N=已删除/作废)
  • STATUS = '2':单据已提交(1=未提交,2=已提交,3=审批中)

查询模板:

-- 查询有效且已提交的业务单据
SELECT * FROM <业务表名>
WHERE ISACTIVE = 'Y' AND STATUS = '2'
-- 其他业务条件...

字段含义:

字段 值 业务含义
ISACTIVE 'Y' 单据有效,可参与统计
ISACTIVE 'N' 单据已删除/作废,应排除
STATUS '1' 草稿/未提交,应排除
STATUS '2' 已提交,可参与统计
STATUS '3' 审批中,通常排除(除非统计审批流程)

应用场景:

  • 统计销售额、销售量 → 必须用 ISACTIVE='Y' AND STATUS='2'
  • 查询历史订单 → 必须用 ISACTIVE='Y' AND STATUS='2'
  • 分析业务趋势 → 必须用 ISACTIVE='Y' AND STATUS='2'

注意事项:

  1. 明细表(如 M_RETAILITEM)通常继承主表状态,但有时也有自己的状态字段
  2. 部分表可能使用 ISSTOP 代替 ISACTIVE,逻辑相反('Y'=停用)
  3. 查询前应先通过 AD_COLUMN 确认字段名和值域

数据权限系统

GET_USERSPERMSQL 函数

数据库内置 get_userspermsql 函数,用于获取用户的数据权限过滤条件。

函数签名:

FUNCTION get_userspermsql(
    p_users_id NUMBER,   -- 用户ID (USERS.ID)
    p_tableid  NUMBER,   -- 表ID (AD_TABLE.ID)
    p_col      VARCHAR2  -- 字段名 (AD_COLUMN.DBNAME),可为NULL
) RETURN CLOB           -- 返回权限过滤SQL

返回值:

  • 空字符串:全权限(无需过滤)
  • SQL条件:如 C_STORE_ID IN (...),需拼接到 WHERE 子句

权限模型:

用户 → GROUPUSER → 用户组 → GROUPPERM → 安全目录 → 权限SQL
                              ↓
                          AD_TABLE.DIRECTORY_ID

使用权限过滤查询

1. 查询用户权限:

python oracle_skill.py perm 940 12983

返回:

{
  "user_id": "940",
  "table_id": "12983",
  "perm_sql": "M_OTHER_INOUT.C_STORE_ID IN(...)",
  "has_restriction": true
}

2. 带权限过滤的查询:

python oracle_skill.py qperm 940 12983 "SELECT * FROM M_OTHER_INOUT WHERE BILLDATE=20260501"

自动拼接权限条件后执行:

SELECT * FROM M_OTHER_INOUT 
WHERE BILLDATE=20260501 
AND M_OTHER_INOUT.C_STORE_ID IN(...)

常用表ID参考

表名 AD_TABLE.ID 说明
M_RETAIL 12964 零售单主表
M_RETAILITEM 12965 零售明细
M_OTHER_INOUT 12983 其他出入库
C_STORE_CHKDAY 18182 门店盘点日

故障排查

问题 排查
无法连接中转服务 检查 transit_url 地址和端口
agent not found 确认 Agent 已启动并连接成功
请求超时 Agent 可能卡住,增大 timeout 参数
Oracle 连接失败 检查 Agent 的 config.json 中 Oracle 配置

Oracle 日常运维监控触发

当用户说“给我 HENLO 的 Oracle 运维报告”、“生成 HENLO 数据库日报”、“做一次 HENLO Oracle 巡检”这类请求时,调用:

python scripts/oracle_skill.py ops_report HENLO

当用户询问单项运维状态时,调用 ops <item> [clientCode]:

python scripts/oracle_skill.py ops blocking_locks HENLO
python scripts/oracle_skill.py ops active_slow_sql HENLO
python scripts/oracle_skill.py ops ora_errors HENLO

常用自然语言映射:

用户意图 命令
有没有锁阻塞 ops blocking_locks <clientCode>
当前有没有慢 SQL ops active_slow_sql <clientCode>
最近 ORA 错误 ops ora_errors <clientCode>
UNDO 风险 ops undo <clientCode>
IO 等待 ops io_waits <clientCode>
内存使用 ops memory <clientCode>
失效对象 ops invalid_objects <clientCode>

涉及 SYS/DBA 权限视图时,Agent 会优先调用 SYS.HENLO_ORA_MONITOR;如果不可用,再尝试当前登录账号下的 HENLO_ORA_MONITOR。如果两个函数都不存在或未授权,输出两种安装方案:有 SYS 账号时安装到 SYS 并授权;没有 SYS 账号但当前登录账号已有系统视图查询权限时,安装到当前账号后重试。

服务器体检报告触发

当用户说“给我 HENLO 的服务器体检报告”、“查询 HENLO 的服务器状态”、“看看 HENLO 的备份情况”这类请求时,调用:

python scripts/oracle_skill.py checkup HENLO

如果用户没有指定客户服务器编号,则调用:

python scripts/oracle_skill.py checkup

输出字段固定为 clientCode、info_cpu_rate、info_memory_rate、info_memory、bak_path、bak_lastdate、computer。clientCode 是客户服务器编号,非必填;不传时使用当前登录 client。

新增业务记录 SQL 生成规则

当用户要求分析或生成新增业务表记录的 SQL 示例时,仍然保持只读安全边界:skill 可以生成 SQL 和说明,但不能直接通过查询通道执行 INSERT、UPDATE、DELETE、MERGE、DDL 等写操作。

生成新增记录 SQL 时遵守以下默认规则:

  • 主表或子表新增记录的主键 ID 使用 get_sequences('<表名称>') 取值。
  • 如果目标表存在 DOCNO 字段,先查询 AD_COLUMN 中该字段是否配置 SEQUENCENAME 单据编号生成器。
  • 如果 DOCNO 对应的 SEQUENCENAME 有值,则单据编号使用 Get_SequenceNo('<SEQUENCENAME>', 37) 取值。
  • 如果目标表存在 AD_CLIENT_ID 字段,默认值使用 37。
  • 如果目标表存在 AD_ORG_ID 字段,默认值使用 27。
  • 子表的 AD_CLIENT_ID 和 AD_ORG_ID 默认取父表记录中对应字段值,不单独写固定值。
  • 新增业务表单时,如果目标表存在 STATUS、STATUSERID、STATUSTIME 字段,通常只给 STATUS 赋默认值 '1',不对 STATUSERID、STATUSTIME 赋值。
  • STATUS='1' 表示草稿/未提交;提交人、提交时间等字段由提交动作或提交存储过程处理。
  • 如果用户明确提到“提交”,通常不是直接把 STATUS 改成 '2',而是应先查询 AD_TABLE.PROC_SUBMIT,按该表配置的提交存储过程理解提交逻辑。

查询 DOCNO 编号生成器示例:

SELECT SEQUENCENAME
FROM AD_COLUMN
WHERE AD_TABLE_ID = (SELECT ID FROM AD_TABLE WHERE NAME = '<表名称>')
  AND UPPER(DBNAME) = 'DOCNO'

字段值域映射规则(AD_COLUMN / AD_LIMITVALUE)

当用户要求解释字段含义、生成查询条件、分析业务类型,或生成新增业务记录 SQL 示例时,如果目标字段在 AD_COLUMN 中的 OBTAINMANNER 值为 select,必须继续通过 AD_LIMITVALUE_GROUP_ID 查询 AD_LIMITVALUE,拿到显示值与数据库实际值的映射关系。

关键规则:

  • AD_COLUMN.OBTAINMANNER = 'select' 表示该字段是受限值列表。
  • AD_COLUMN.AD_LIMITVALUE_GROUP_ID 关联 AD_LIMITVALUE.AD_LIMITVALUE_GROUP_ID。
  • 用户通常说的是显示值,例如“券核销”。
  • SQL 查询条件和新增记录 SQL 必须使用数据库实际值,例如 VOU_USED。
  • 不要把显示值直接写入业务表字段,除非 AD_LIMITVALUE 查询结果证明显示值就是实际值。

示例:XH_ORDER_FTP.BILLTYPE 字段,当显示值为“券核销”时,对应的数据库实际值是 VOU_USED。因此用户说“类型为券核销”时,应生成:

XH_ORDER_FTP.BILLTYPE = 'VOU_USED'

查询字段值域映射模板:

SELECT c.DBNAME,
       c.NAME,
       c.OBTAINMANNER,
       c.AD_LIMITVALUE_GROUP_ID,
       v.VALUE,
       v.NAME AS DISPLAY_NAME
FROM AD_COLUMN c
LEFT JOIN AD_LIMITVALUE v ON v.AD_LIMITVALUE_GROUP_ID = c.AD_LIMITVALUE_GROUP_ID
WHERE c.AD_TABLE_ID = (SELECT ID FROM AD_TABLE WHERE NAME = '<表名称>')
  AND UPPER(c.DBNAME) = UPPER('<字段名>')
ORDER BY v.ORDERNO, v.ID

使用时先查字段:

SELECT ID, DBNAME, NAME, DESCRIPTION, OBTAINMANNER, AD_LIMITVALUE_GROUP_ID
FROM AD_COLUMN
WHERE AD_TABLE_ID = (SELECT ID FROM AD_TABLE WHERE NAME = 'XH_ORDER_FTP')
  AND UPPER(DBNAME) = 'BILLTYPE'

如果 OBTAINMANNER='select' 且 AD_LIMITVALUE_GROUP_ID 有值,再查:

SELECT VALUE, NAME AS DISPLAY_NAME
FROM AD_LIMITVALUE
WHERE AD_LIMITVALUE_GROUP_ID = <AD_LIMITVALUE_GROUP_ID>
ORDER BY ORDERNO, ID