22 KiB
Oracle Jump Query Skill
通过中转服务查询远程 Oracle 数据库的 AI 技能,支持存储过程分析、表结构查询、数据权限控制。
架构
用户/AI → 中转服务 (:6357) → WebSocket → Agent → Oracle 数据库
- 中转服务:转发 HTTP 请求到数据库服务器的 Agent
- Agent:部署在数据库服务器,通过 WebSocket 连接中转服务,无需开放数据库端口
- 安全:数据库服务器仅需出站 WebSocket 连接,防火墙友好
环境要求
- Python 3.6+
pip install requests
维护来源
本 skill 的 Git 地址:
私有主库:https://gitea.momozhua.site/qiangayi/oracle-jump-query
公开镜像:https://gitea.momozhua.site/qiangayi/oracle-jump-query-public
开发和发布使用私有主库;每次推送私有 Git 后必须同步更新无历史公共镜像,新用户可从公共镜像下载。同步前必须检查敏感文件并完成测试。C:\Users\qiang\.codex\skills\oracle-jump-query 是安装后的运行目录,不作为长期源码目录。
对话隔离与启动提速(1.5.54)
每个对话只需确定一次目标客户:从用户提供的客户、工单或当前对话上下文解析出明确 client code,后续沿用,用户明确切换时更新。不得从其他对话或共享配置的“当前客户”推断本对话目标;无法确定时询问客户,名称有多个匹配时列出候选,不猜测。查询客户名称映射优先读取本地 scripts/config.json 的 client_list(只读取 code/title/name,不输出 token);找不到时执行 clients 刷新授权列表。
助手每次调用单 Agent 命令时自动在命令名后、业务参数前带 --client CODE,用户无需在每句话重复客户。该参数仅影响本次命令,不修改默认客户;命令开始即固定客户、中转地址,多步查询、权限获取、预检、下载和续登重试保持原目标。旧位置参数仍兼容;与 --client 不一致时直接报错。未指定时兼容本地默认客户,但为空则停止,不选择占位服务器或第一个客户。
常规查询无需先执行 status、switch 或手动登录:CLI 自动处理 token 缺失/过期,401 时复用其他进程的新 token 或可信设备续登,仅重发一次。设备未审批、撤销、过期或无本机密钥时提示原因,再由用户提供登录密钥;不自动注册设备。403、参数错误、客户离线直接返回,查询超时不重复执行。status 用于排障,switch 仅用于显式维护旧用法的默认客户。
普通查询及元数据命令可在业务参数前加 --json,stdout 只返回 JSON(含 client_code),登录、更新和诊断提示输出到 stderr。完整能力定义仍可用 capabilities --json 按需读取。
python scripts/oracle_skill.py capabilities --brief --json
python scripts/oracle_skill.py describe --client WEIRUI --json BOSNDS3 M_PRODUCT
python scripts/oracle_skill.py query --client WEIRUI --json "SELECT ID, NAME FROM M_PRODUCT WHERE ID=123 AND ROWNUM<=1"
python scripts/oracle_skill.py qperm --client HENLO --json 940 12983 "SELECT ID FROM M_OTHER_INOUT WHERE ID=123 AND ROWNUM<=1"
python scripts/oracle_skill.py ops_report --client HENLO
python scripts/oracle_skill.py awr_download --client WEIRUI 20261008
快速开始
更多面向日常使用的问法和操作流程,见 操作示例。
1. 配置
编辑 scripts/config.json:
{
"transit_url": "https://ts.henlo.net",
"server_id": "",
"access_token": "",
"expires_at": ""
}
先登录中转机后再查询:
python oracle_skill.py login <secretKey> [clientCode]
python oracle_skill.py status
secretKey 只用于登录请求,不会保存到本地配置文件。clientCode 是客户服务器编号,非必填;不传时中转机会默认选择 BOS 返回的第一个可用 client。登录成功后本地仅保存中转机签发的 access_token、过期时间和可访问 client 列表。
同一个 secretKey 同时只允许一个设备在线。另一台设备重新登录后,当前设备的 token 会立即失效,需要重新执行 login <secretKey> [clientCode]。
2. 运行交互模式
cd scripts
python oracle_skill.py
3. 运行指定命令
# 分析存储过程
python oracle_skill.py analyze bosnds3 M_RETAIL_SUBMIT
# 查询表结构
python oracle_skill.py describe bosnds3 xcx_so
# 执行 SELECT 查询:生产表必须带业务过滤条件和行数限制
python oracle_skill.py query "SELECT * FROM M_RETAIL WHERE BILLDATE = 20260501 AND ROWNUM <= 20"
# 获取用户数据权限
python oracle_skill.py perm 940 12983
命令列表
| 命令 | 说明 | 示例 |
|---|---|---|
analyze <schema> <proc> |
完整分析存储过程(源码+依赖+表+触发器) | analyze bosnds3 M_RETAIL_SUBMIT |
list <schema> |
列出 schema 下所有存储过程 | list bosnds3 |
source <schema> <proc> |
获取存储过程源码 | source bosnds3 M_RETAIL_SUBMIT |
deps <schema> <proc> |
获取依赖(表/存储过程) | deps bosnds3 M_RETAIL_SUBMIT |
describe <schema> <table> |
查询表结构(列、类型、索引、行数) | describe bosnds3 xcx_so |
query <SQL> |
执行 SELECT 查询(仅支持 SELECT;生产表必须带过滤条件和行数限制) | query SELECT * FROM M_RETAIL WHERE BILLDATE=20260501 AND ROWNUM<=20 |
tablespace / tablespaces |
查询表空间使用情况 | tablespace |
perm <userId> <tableId> |
查询用户数据权限 | perm 940 12983 |
qperm <userId> <tableId> <SQL> |
带权限过滤的查询 | qperm 940 12983 SELECT * FROM M_OTHER_INOUT |
login <secretKey> [clientCode] |
登录中转机 + 选择客户服务器,clientCode 非必填 | login mykey HENLO |
logout |
登出中转机并清除本地 token | logout |
status |
查看中转机登录状态 + 当前 client | status |
| `switch <clientCode | clientName>` | 按 code 或名称切换 client;找不到时自动刷新 client 列表 |
clients |
无感刷新当前用户最新授权的 client 列表及在线状态(只使用当前登录 token) | clients |
inspection_report [clientCode] [--json] [--html [path]] [--markdown [path]] |
生成服务器巡检报告并归档,默认导出固定格式 HTML,可同时导出 Markdown | inspection_report HENLO --markdown |
inspection_latest [clientCode] [--refresh] [--json] [--html [path]] [--markdown [path]] |
查看最近归档巡检报告并默认导出 HTML;加 --refresh 时重新生成 |
inspection_latest HENLO --refresh --markdown |
inspection_get <id> [--json] [--html [path]] [--markdown [path]] |
按归档 ID 查看历史巡检报告并默认导出 HTML | inspection_get 123 --markdown |
agent_update [clientCode] [timeout] |
触发客户 Agent 自动更新,升级包由 Agent 从 OSS 下载 | agent_update HENLO 300 |
log_info <path> [--client code] |
验证服务器绝对日志路径和文件元数据 | log_info "D:\logs\app.log" --client AHMW --json |
log_tail <path> [--client code] |
有界读取日志末尾内容 | log_tail "D:\logs\app.log" --client AHMW --lines 200 |
log_search <path> <pattern...> |
在 Agent 本机按关键词或正则流式搜索日志 | log_search "D:\logs\app.log" ERROR --client AHMW --json |
log_enable [clientCode] / log_disable [clientCode] |
持久化开启或关闭目标客户日志分析 | log_enable AHMW |
discover [schema] [filter] |
发现核心业务表 | discover bosnds3 M_% |
nl2sql <schema> <question> |
自然语言转 SQL | nl2sql bosnds3 查询花都二店5月销售额 |
servers |
列出在线 Agent | servers |
health |
检查中转服务状态 | health |
capabilities --json |
获取版本和命令定义(供程序调用) | capabilities --json |
生产查询限制
查询业务表时一定要带条件查询,不要直接查询整表。生产环境中业务表通常数据量很大,无条件 SELECT * FROM <table> 可能返回大量结果、拖慢 Agent 或影响数据库。
建议:
- 必须包含
WHERE条件,优先使用日期、单号、门店、客户、状态、主键等业务过滤条件。 - 必须加
ROWNUM <= N或分页限制。 - 用户没有提供条件时,先追问日期、单号、门店等范围;不要直接查整表。
- 只想了解字段时,优先使用
describe、AD_TABLE、AD_COLUMN。
推荐:
SELECT *
FROM M_RETAIL
WHERE BILLDATE = 20260501
AND STATUS = '2'
AND ROWNUM <= 20
不要这样查:
SELECT * FROM M_RETAIL
品小二中文条件
品小二环境存在已知字符集转换问题,中文条件直接写成 LIKE '%中文%' 可能返回 0 行。查询中文值时使用 Oracle UNISTR Unicode 转义,例如:
SELECT ID, NAME, DESCRIPTION
FROM AD_TABLE
WHERE DESCRIPTION LIKE '%' || UNISTR('\96F6\552E\5355') || '%'
AND ROWNUM <= 20
直接中文字面量查不到时,先用 UNISTR 形式重试;这条是品小二的客户级兼容规则。其他 client 若已验证直接中文字面量可用,不必强制改写,但 UNISTR 可作为跨环境复用和避免传输编码转换的通用兜底。
常用业务对象说明
- “商品”“款号”通常指
M_PRODUCT表。 - “条码”“SKU”通常指
M_PRODUCT_ALIAS表。 - 查询条码/SKU 时,首查
M_PRODUCT_ALIAS.NO字段。 - 款号和条码是一对多关系:一个款号可以对应多个条码/SKU。
- 商品明细里常见的
M_PRODUCT_ID、M_PRODUCTALIAS_ID、M_ATTRIBUTESETINSTANCE_ID分别对应款号、条码、色码属性 ASI。 M_ATTRIBUTESETINSTANCE的VALUE1、VALUE1_CODE、VALUE1_ID对应颜色名称、颜色编号、颜色表M_COLOR.ID;VALUE2、VALUE2_CODE、VALUE2_ID对应尺码名称、尺码编号、尺码表M_SIZE.ID。- 涉及库存查询时,通常查询
V_FA_STORAGE视图。 V_FA_STORAGE数据量很大,必须通过店仓 + 款号/条码条件查询,不要直接查整张库存视图。
库存查询建议:
- 用户只说“查库存”但没有给出店仓或款号/条码时,先追问条件。
- 通过款号查库存时,围绕
M_PRODUCT找商品。 - 通过条码/SKU 查库存时,优先用
M_PRODUCT_ALIAS.NO找条码,再关联到商品。 - 通过颜色/尺码查商品明细或库存时,优先用
M_ATTRIBUTESETINSTANCE的VALUE1_ID/VALUE2_ID或VALUE1_CODE/VALUE2_CODE过滤。 - 查询
V_FA_STORAGE时必须加店仓条件、款号/条码条件和ROWNUM或分页限制。
应用场景
场景一:分析存储过程业务逻辑
分析 M_RETAIL_SUBMIT 存储过程:
输入:python oracle_skill.py analyze bosnds3 M_RETAIL_SUBMIT
输出:
- 完整源码(PL/SQL)
- 依赖的表、视图、嵌套存储过程
- 涉及的表结构(列名、类型、长度)
- 触发器列表
场景二:查询数据字典
通过 AD_TABLE、AD_COLUMN 查询表和字段的业务含义:
-- 查询 M_RETAIL 的字段描述
SELECT DBNAME, NAME, DESCRIPTION, COLTYPE
FROM AD_COLUMN
WHERE AD_TABLE_ID = (SELECT ID FROM AD_TABLE WHERE NAME = 'M_RETAIL')
ORDER BY ORDERNO
也可以通过 BOS 元数据体系分析系统菜单、模块目录和业务表结构。AD_TABLE_TEXT 过程显示 BOS 的系统地图主要由 AD_SUBSYSTEM -> AD_TABLECATEGORY -> AD_ACCORDION -> AD_TABLE -> AD_COLUMN / AD_REFBYTABLE / AD_ACTION 驱动,报表模板由 AD_CXTAB 相关表维护,权限挂载点在 DIRECTORY。
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
场景三:带权限过滤的查询
普通用户查询时自动拼接权限条件(如按门店过滤):
输入:python oracle_skill.py qperm 940 12983 SELECT * FROM M_OTHER_INOUT
自动拼接:C_STORE_ID IN(...) WHERE 条件
输出:仅返回用户有权限查看的数据
数据权限模型
数据库内置 get_userspermsql 函数:
FUNCTION get_userspermsql(
p_users_id NUMBER, -- 用户ID
p_tableid NUMBER, -- 表ID (AD_TABLE.ID)
p_col VARCHAR2 -- 字段名,可为NULL
) RETURN CLOB -- 返回权限过滤SQL
返回值示例:
- 空字符串:全权限(无需过滤)
C_STORE_ID IN(1,2,3):仅可查看指定门店
常见问题
| 问题 | 解决方法 |
|---|---|
| 无法连接中转服务 | 检查 config.json 中的 transit_url 地址和端口 |
| agent not found | 确认 Agent 已启动并连接成功 |
| 请求超时 | Agent 可能卡住,增大 timeout 参数 |
相关项目
- 恒诺云打印 Print_Tool - .NET 10 升级项目
- Henlo_Mid 通用接口 - 企业内部系统集成
License
MIT
服务器巡检报告
当用户询问“给我 HENLO 的服务器体检报告 / 巡检报告 / 运维体检报告 / 备份和资源情况”时,统一调用新版巡检入口:
python scripts/oracle_skill.py inspection_report HENLO
python scripts/oracle_skill.py inspection_report HENLO --markdown
python scripts/oracle_skill.py inspection_latest HENLO --refresh --markdown
巡检命令成功后默认把固定格式 HTML 写入 outputs/。增加 --markdown(或 --md)会同时生成 Markdown;--html 和 --markdown 后均可指定自定义输出路径。
HTML 导出使用固定模板,CSS、章节顺序和表格结构保持不变,只替换报告编号、采集时间、指标值、告警和明细行。不传路径时写入 skill 目录下的 outputs/。
当前报告支持服务器 IP、系统版本、启动时间/运行时长、关键进程、TCP 连接统计,以及 Oracle ACTIVE/总会话数和 Buffer/Library Cache 命中率。AWR 已记录在未来开发计划中,当前版本不执行 AWR 采集;详细边界见 references/oracle-ops-and-checkup.md。
Oracle 日常运维监控
单项监控:
python scripts/oracle_skill.py ops active_slow_sql HENLO
python scripts/oracle_skill.py ops blocking_locks HENLO
python scripts/oracle_skill.py ops ora_errors HENLO
���一日报:
python scripts/oracle_skill.py ops_report HENLO
clientCode 可省略,不传时使用当前登录 client。第一版支持的监控项包括:active_slow_sql、history_top_sql、fullscan_sql、plan_heavy_sql、blocking_locks、long_transactions、inactive_sessions、datafiles、undo、memory、io_waits、background_process、ora_errors、invalid_objects、tablespace。
涉及 v$、dba_、AWR、alert log 等 SYS/DBA 权限视图时,Agent 会优先调用 SYS.HENLO_ORA_MONITOR,如果不可用则自动尝试当前登录账号下的 HENLO_ORA_MONITOR。如果两个函数都不存在或未授权,命令会输出两种安装方案:有 SYS 账号时安装到 SYS 并授权;没有 SYS 账号但当前登录账号已有系统视图查询权限时,直接安装到当前账号。
生成巡检报告时,Skill 会先执行 SYS 函数版本与授权预检。预检失败后会读取目标 Agent 的实际 Oracle schema,并把完整 SQL 中的授权账号自动替换为该 schema;输出中不得保留 <AGENT_SCHEMA> 占位符。无法取得 schema 时停止生成报告并提示检查 Agent 配置。
新增业务记录 SQL 生成规则
业务单据的商品明细有新增功能、需要通过商品新增输入框输入条码录入时,AD_TABLE.CLASSNAME 配置为 nds.schema.AttributeDetailSupportTableImpl。明细通常有商品 ID M_PRODUCT_ID、条码 ID M_PRODUCTALIAS_ID、ASI ID M_ATTRIBUTESETINSTANCE_ID;ASI 字段读写规则一般为 1100000000,只在新增时可见。字段名称和明细新增动作需核实,详细规则见 商品明细的条码新增配置。
新建 BOS 业务单据表单时,在八个基础字段和主键之上通常还需 DOCNO、STATUS、提交时间、提交人;ISACTIVE 已在基础字段中。表级读写规则默认 MDQSV。DOCNO 维护编号生成器,读写方式为“单据编号”;STATUS、ISACTIVE 使用“下拉框选项”,选项名称分别为 STATUS、YESNO,字段翻译器均为 nds.web.alert.LimitValueAlerter,默认值分别为 1、Y。三个字段的读写打印规则均为 0010111111,保留前导零。提交人和提交时间由提交动作维护;详细规则见 业务单据表单默认配置。
本 skill 默认只读,不直接执行写库操作;当需要分析或生成新增业务记录 SQL 示例时,遵守以下 BOS 默认取值规则:
-
新增记录主键
ID使用get_sequences('<表名称>')。 -
如果表存在
DOCNO字段,先到AD_COLUMN查询该字段的SEQUENCENAME。 -
取单号函数为
Get_SequenceNo('<CODE>', AD_CLIENT_ID);默认CODE取该单据DOCNO字段对应的AD_COLUMN.SEQUENCENAME值,第二个参数取单据实际的AD_CLIENT_ID,确认是37时才写37。配置为空时不猜测CODE,特殊业务按实际配置和过程逻辑核实;只生成 SQL 示例,不通过查询通道调用取号函数。 -
取号
CODE的定义在AD_SEQUENCE表,分析编号规则时沿DOCNO -> AD_COLUMN.SEQUENCENAME -> AD_SEQUENCE核实。 -
如果表存在
AD_CLIENT_ID字段,默认值为37。 -
如果表存在
AD_ORG_ID字段,默认值为27。 -
子表
AD_CLIENT_ID、AD_ORG_ID默认继承父表对应字段值。 -
新增业务表单时,如果表存在
STATUS、STATUSERID、STATUSTIME字段,通常只设置STATUS='1',不对STATUSERID、STATUSTIME赋值。 -
STATUS='1'表示草稿/未提交;提交相关字段通常由提交逻辑维护。 -
如果用户提到“提交”,通常指该表在
AD_TABLE.PROC_SUBMIT中配置的提交存储过程。 -
生成提交 SQL 或说明提交流程时,如果已知
userId,调用AD_TABLE.PROC_SUBMIT前需要先更新主单据修改人和修改时间,再调用提交存储过程;修改人、修改时间字段名必须先通过AD_COLUMN或表结构确认,不要凭经验硬写字段名。 -
分析 BOS 业务表时,同时查看
AD_TABLE的表单事件过程:HAS_TRIG_BD='Y'时TRIG_BD为删除前触发过程(bd),HAS_TRIG_AC='Y'时TRIG_AC为新增后触发过程(ac),HAS_TRIG_AM='Y'时TRIG_AM为修改后触发过程(am)。
字段值域映射规则
当 AD_COLUMN 中某个字段的 OBTAINMANNER 值为 select 时,该字段的可选值不应直接猜测,需要通过 AD_LIMITVALUE_GROUP_ID 查询子表 AD_LIMITVALUE,取得“数据库实际值”和“显示值”的映射关系。
示例:XH_ORDER_FTP.BILLTYPE 的显示值“券核销”,对应实际入库值是 VOU_USED。当用户说“类型为券核销”时,生成查询条件或新增记录 SQL 应使用实际值:
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
Agent 版本查询
自然语言提示词:查询所有客户的 Agent 版本号;或查询 HENLO、RENBEN 的 Agent 版本号。
python scripts/oracle_skill.py version agent HENLO RENBEN --json
python scripts/oracle_skill.py version agent --all --json
从 Git 更新 Skill
每日自动更新与使用记录
CLI 启动时记录最后使用时间;按运行电脑本地日期,每个使用日首次启动自动 fetch origin main,检测到新版本时仅在 main 分支执行快进安装,并重新启动当前命令使用新版本。同一天后续启动不重复抓取;未使用的日期不运行后台任务。每次开始应用 Skill 时先运行 python scripts/oracle_skill.py capabilities --brief --json,使只参考业务知识的任务也触发检测。
本机状态文件为 scripts/update-state.json:last_used_at 记录最后使用时间,last_checked_at / last_check_date 记录检测时间和日期,status 记录 checking、up_to_date、updated、update_blocked、check_failed 或 not_git;检测完成时可包含本机和远端提交 ID。状态、锁和临时文件不提交 Git,不保存 token、密钥、SQL 或查询结果。
自动更新保留本机 config.json 和 scripts/config.json;源码有未提交修改、存在暂存修改、分支分叉或配置冲突时暂停安装并继续原命令。抓取超时为 10 秒,认证和网络失败不阻止业务命令,也不在当天每次调用时重试;可手动执行 git pull --ff-only origin main 重试。提示写入 stderr,stdout 的 JSON 输出不受影响。Git checkout 使用自己的 origin,私有和公共安装均可使用;无 .git 的下载目录只记录使用时间。
Skill 仅通过 Gitea Git 仓库更新,不使用 OSS 或 skill_update 命令。源码仓库完成修改并推送私有库后,必须同步更新无历史公共镜像;随后在已安装目录执行:
cd C:\Users\qiang\.codex\skills\oracle-jump-query
git pull --ff-only origin main
python scripts/oracle_skill.py capabilities --json
在线 Agent 直接确认当前版本;离线客户返回最后一次心跳版本和离线状态。