ops-wiki-agent-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/agents/docs-target-catalog.agent.md +52 -0
- package/.github/agents/docs-target-queue-from-catalog.agent.md +34 -0
- package/.github/agents/source-code-to-spec-documenter.agent.md +39 -0
- package/.github/agents/source-code-to-spec-reviewer.agent.md +51 -0
- package/.github/agents/source-code-to-system-ops-overview.agent.md +39 -0
- package/.github/prompts/00-generate-target-all-spec.prompt.md +35 -0
- package/.github/prompts/01-generate-target-foundation-spec.prompt.md +35 -0
- package/.github/prompts/02-generate-target-architecture-spec.prompt.md +35 -0
- package/.github/prompts/03-generate-target-ops-spec.prompt.md +35 -0
- package/.github/prompts/04-review-target-spec.prompt.md +24 -0
- package/.github/prompts/docs-target-catalog.prompt.md +32 -0
- package/.github/prompts/docs-target-queue-from-catalog.prompt.md +28 -0
- package/.github/prompts/generate-system-ops-overview.prompt.md +62 -0
- package/.github/skills/database-query/SKILL.md +140 -0
- package/.github/skills/database-query/references/client-commands.md +189 -0
- package/.github/skills/database-query/references/query-safety.md +109 -0
- package/.github/skills/database-query/scripts/find_db_config.py +273 -0
- package/.github/skills/docs-target-catalog/SKILL.md +194 -0
- package/.github/skills/docs-target-catalog/references/docs-target-queue-conversion.md +164 -0
- package/.github/skills/docs-target-catalog/references/entrypoint-source-patterns.md +83 -0
- package/.github/skills/docs-target-catalog/references/output-templates.md +168 -0
- package/.github/skills/docs-target-queue-from-catalog/SKILL.md +255 -0
- package/.github/skills/docs-target-queue-from-catalog/references/docs-target-queue-contract.md +125 -0
- package/.github/skills/docs-target-queue-from-catalog/references/metadata-acquisition-patterns.md +149 -0
- package/.github/skills/docs-target-queue-from-catalog/scripts/write_documentation_target_queue.py +527 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/SKILL.md +128 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/01-system-overview-and-business-scenarios-guideline.md +172 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/02-core-architecture-flow-data-logic-guideline.md +637 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/03-error-ops-scenario-coverage-guideline.md +533 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/supporting-output-format-diagram-and-example-reference.md +523 -0
- package/.github/skills/source-code-to-spec-documenter/SKILL.md +80 -0
- package/.github/skills/source-code-to-spec-documenter/references/generation-handoff-contract.md +155 -0
- package/.github/skills/source-code-to-spec-documenter/references/generation-workflow.md +184 -0
- package/.github/skills/source-code-to-spec-documenter/references/source-tracing-rules.md +271 -0
- package/.github/skills/source-code-to-spec-documenter/references/target-queue-contract.md +78 -0
- package/.github/skills/source-code-to-spec-documenter/scripts/spec_queue.py +222 -0
- package/.github/skills/source-code-to-spec-tools/SKILL.md +117 -0
- package/.github/skills/source-code-to-spec-tools/references/repository-artifact-contract.md +122 -0
- package/.github/skills/source-code-to-spec-tools/references/target-queue-schema-contract.md +116 -0
- package/.github/skills/source-code-to-spec-tools/references/terminology-contract.md +121 -0
- package/.github/skills/source-code-to-spec-tools/scripts/catalog_query.py +324 -0
- package/.github/skills/source-code-to-spec-tools/scripts/queue_contract.py +210 -0
- package/.github/skills/source-code-to-spec-tools/scripts/source_lookup.py +360 -0
- package/.github/skills/source-code-to-spec-tools/scripts/target_query.py +407 -0
- package/.github/skills/source-code-to-system-ops-overview/SKILL.md +82 -0
- package/.github/skills/source-code-to-system-ops-overview/references/system-operations-overview-guideline.md +332 -0
- package/README.md +116 -0
- package/ops-wiki-agent-kit.js +173 -0
- package/package.json +22 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-query
|
|
3
|
+
description: "通用 DB 查詢 workflow。當 agent 需要從 repo 找出 DB 連線資訊、選擇安全的查詢方式,並透過 helper scripts、native CLI clients 或 repo 既有工具,對 Oracle、PostgreSQL、SQL Server、MySQL、MariaDB、SQLite、IBM Db2、H2 或其他 SQL databases 執行 read-only SQL investigation 時使用。"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Database Query
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
用這個 skill 協助 AI agent 在陌生 repo 中查詢 DB。流程優先從 repo 內找既有 DB 連線設定與查詢工具,找不到完整資訊時才向 user 要求必要連線資料。
|
|
11
|
+
|
|
12
|
+
預設只做 read-only investigation。除非 user 明確要求且確認目標環境,否則不要執行 `INSERT`、`UPDATE`、`DELETE`、`MERGE`、`TRUNCATE`、`CREATE`、`ALTER`、`DROP`、`GRANT`、`REVOKE`,或任何具有 side effects 的 stored procedure/function call。
|
|
13
|
+
|
|
14
|
+
## Core Rules
|
|
15
|
+
|
|
16
|
+
- 除非有明確證據證明 DB 是 local、可丟棄或僅供 test,否則一律視為 live DB。
|
|
17
|
+
- 優先使用 repo 既有的 helper scripts、已設定好的 app tools 或 native clients,不要先自行發明新的 connector。
|
|
18
|
+
- 回答中絕對不要輸出 plaintext passwords、tokens、wallet paths、private keys,或包含完整 credentials 的 URL。
|
|
19
|
+
- 不要建立或提交新的 credential files。需要 credentials 時,使用 session environment variables 或 user 提供的暫時性值。
|
|
20
|
+
- 如果存在多組 DB config,查詢前先辨識目標 environment:`local`、`dev`、`test`、`uat`、`stage`、`prod`、tenant、schema、service 或 container。
|
|
21
|
+
- 若 repo 同時出現多個 DB backend、datasource profile 或 environment 線索,`SELECT 1` 成功只代表 client 可連線,不代表你已連到正確的 business authority。開始 inventory / business query 前,必須記錄目前 session 的 user、schema、service / database identity。
|
|
22
|
+
- 查詢要有邊界。加入 row limits、filters、schema qualifiers,以及精準的 column lists。
|
|
23
|
+
- 記錄實際執行的 SQL、DB type、connection info 來源、row counts 與不確定性,並遮蔽敏感的 connection fields。
|
|
24
|
+
- 若 repo 提供 PowerShell / shell helper 包裝 native client,優先直接呼叫 helper 或先產生 temp SQL/file 再執行;不要把 helper 再嵌進過長、重 quoting 的 one-liner,避免把 shell 展開問題誤判成 DB query failure。
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
### 1. Clarify The Query Goal
|
|
29
|
+
|
|
30
|
+
先確認 user 要的是哪一類 DB 查詢:
|
|
31
|
+
|
|
32
|
+
- schema discovery:table、column、index、constraint、view、sequence、procedure/package。
|
|
33
|
+
- data validation:count、sample rows、status distribution、date range、duplicate check。
|
|
34
|
+
- application debugging:從 source code 追蹤 table usage、驗證預期 records、比對 config values。
|
|
35
|
+
- operational check:job status、queue state、scheduler metadata、lock/session inspection。
|
|
36
|
+
- migration/release check:確認 DDL state 或 migration history。
|
|
37
|
+
|
|
38
|
+
如果 user 的需求暗示會修改資料,先停下來要求明確核准與 rollback/backup plan。
|
|
39
|
+
|
|
40
|
+
### 2. Discover DB Type And Connection Candidates
|
|
41
|
+
|
|
42
|
+
先從 repo 取得證據,不要直接詢問 user:
|
|
43
|
+
|
|
44
|
+
1. 從 repo root 執行 `python -B .github/skills/database-query/scripts/find_db_config.py <repo-path>`,找出 DB URLs、datasource keys、env placeholders 與 config files,並確保輸出已做 redaction。使用 `-B` 避免留下 `__pycache__` 或 `*.pyc` runtime cache。
|
|
45
|
+
2. 在整個 repo 的 source、config、scripts、deployment manifests 與 dependency metadata 中搜尋 DB drivers、connection strings、ORM/data-access packages、DSN 與 env var patterns;不要假設 repo 一定是 Java 或 Web 專案:
|
|
46
|
+
- generic: `DATABASE_URL`, `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `ConnectionStrings`, `ODBC DSN`, `DSN=`, `Data Source=`, `Server=`, `Host=`, `User ID=`
|
|
47
|
+
- `jdbc:oracle:thin`, `oracle.jdbc`, `tnsnames.ora`, `sqlplus`, `sqlcl`
|
|
48
|
+
- `jdbc:postgresql`, `org.postgresql`, `PGHOST`, `DATABASE_URL`
|
|
49
|
+
- `jdbc:sqlserver`, `com.microsoft.sqlserver`, `sqlcmd`, `Data Source=`
|
|
50
|
+
- `jdbc:mysql`, `jdbc:mariadb`, `com.mysql`, `org.mariadb`
|
|
51
|
+
- `jdbc:db2`, `com.ibm.db2`, `db2 connect`
|
|
52
|
+
- `jdbc:h2`, `jdbc:sqlite`, `sqlite3`
|
|
53
|
+
- Java/JVM: `spring.datasource.*`, `r2dbc.*`, `hibernate.connection.*`, `persistence.xml`, `context.xml`, `javax.sql.DataSource`
|
|
54
|
+
- .NET/C#: `appsettings*.json`, `web.config`, `*.config`, `*.csproj`, `System.Data.SqlClient`, `Microsoft.Data.SqlClient`, `Npgsql`, `Oracle.ManagedDataAccess`, `MySqlConnector`, `EntityFramework`, `Dapper`
|
|
55
|
+
- Node.js/TypeScript: `pg`, `mysql2`, `mssql`, `oracledb`, `typeorm`, `sequelize`, `prisma`, `knex`
|
|
56
|
+
- Python: `sqlalchemy`, `psycopg`, `psycopg2`, `cx_Oracle`, `oracledb`, `pyodbc`, `pymysql`, `sqlite3`
|
|
57
|
+
- PHP/Ruby and other stacks: `PDO`, `mysqli`, `ActiveRecord`, `database.yml`, `config/database.*`
|
|
58
|
+
3. 檢查常見的 config 與 runtime 位置,依 repo 實際技術棧調整,不要只看單一語言慣例:
|
|
59
|
+
- `.env*`, `appsettings*.json`, `web.config`, `*.config`, `database.yml`, `database.*`, `settings.*`
|
|
60
|
+
- `application*.properties`, `application*.yml`, `docker-compose*.yml`
|
|
61
|
+
- `helm/`, `k8s/`, `deployment*.yaml`, `values*.yaml`, `configmap`, `secret`
|
|
62
|
+
- `pom.xml`, `build.gradle`, `*.csproj`, `packages.config`, `package.json`, `requirements.txt`, `pyproject.toml`, `composer.json`, `Gemfile`
|
|
63
|
+
- Jenkins/GitLab CI files, startup scripts, container scripts, scheduled task definitions
|
|
64
|
+
- `config/`, `conf/`, `resources/`, `src/main/resources/`, `WEB-INF/`, `Properties/`, `App_Data/`
|
|
65
|
+
|
|
66
|
+
如果 repo 內只有 `${DB_PASSWORD}` 這類 placeholders,先找出變數名稱,並在可行時檢查目前 process environment。若值不可得,再請 user 提供。
|
|
67
|
+
|
|
68
|
+
### 3. Decide Whether To Prompt User
|
|
69
|
+
|
|
70
|
+
只有在 repo discovery 無法補齊完整 connection profile 時,才詢問 user。
|
|
71
|
+
|
|
72
|
+
只詢問最小必要缺漏資訊:
|
|
73
|
+
|
|
74
|
+
- `db_type`: Oracle, PostgreSQL, SQL Server, MySQL, MariaDB, SQLite, IBM Db2, H2, etc.
|
|
75
|
+
- `host`, `port`, `database` or `service_name`/`SID`, and optional `schema`.
|
|
76
|
+
- `username` and password/token, preferably read-only and temporary.
|
|
77
|
+
- environment name: `local`, `dev`, `test`, `uat`, `prod`.
|
|
78
|
+
- preferred access method if security policy requires one: VPN, bastion, container exec, app helper, wallet, Kerberos, IAM, ODBC DSN.
|
|
79
|
+
|
|
80
|
+
告知 user 可以提供 placeholders 或僅限本次 session 使用的值。不要要求 user 把 secrets 提交進 repo。
|
|
81
|
+
|
|
82
|
+
### 4. Choose The Query Method
|
|
83
|
+
|
|
84
|
+
依照以下順序選擇:
|
|
85
|
+
|
|
86
|
+
1. Existing repo helper: scripts, Makefile/Gradle/Maven tasks, app admin CLI, migration tooling, DAO/repository tests, or documented SQL utilities.
|
|
87
|
+
2. Native DB client:
|
|
88
|
+
- Oracle: `sqlplus` or `sql`
|
|
89
|
+
- PostgreSQL: `psql`
|
|
90
|
+
- SQL Server: `sqlcmd`
|
|
91
|
+
- MySQL/MariaDB: `mysql` or `mariadb`
|
|
92
|
+
- SQLite: `sqlite3`
|
|
93
|
+
- IBM Db2: `db2`
|
|
94
|
+
- H2: app console, JDBC tool, or repo-provided test utility
|
|
95
|
+
3. Container-local client: `docker compose exec`, `kubectl exec`, or DB client inside an app/DB container when local tooling is unavailable.
|
|
96
|
+
4. Temporary helper script in the current work session only if dependencies are already installed or user approves installation. Do not add DB driver dependencies to the repo for a one-off query.
|
|
97
|
+
|
|
98
|
+
可參考 `references/client-commands.md` 取得 native client command templates,並參考 `references/query-safety.md` 了解 read-only 與 row-limit patterns。
|
|
99
|
+
|
|
100
|
+
### 5. Validate Connection With A Minimal Query
|
|
101
|
+
|
|
102
|
+
在正式 investigation 前,先執行無害的 identity/version query:
|
|
103
|
+
|
|
104
|
+
- Oracle: `SELECT 1 FROM dual`
|
|
105
|
+
- PostgreSQL: `SELECT 1`
|
|
106
|
+
- SQL Server: `SELECT 1`
|
|
107
|
+
- MySQL/MariaDB: `SELECT 1`
|
|
108
|
+
- SQLite: `SELECT 1`
|
|
109
|
+
- IBM Db2: `SELECT 1 FROM sysibm.sysdummy1`
|
|
110
|
+
- H2: `SELECT 1`
|
|
111
|
+
|
|
112
|
+
如果 connection 失敗,回報精確但不含 secrets 的錯誤類型:network、auth、service/database name、missing client、missing driver、SSL/TLS、VPN/bastion、permission denied 或 syntax mismatch。
|
|
113
|
+
|
|
114
|
+
若 repo 有多組連線線索、同時存在多個 datasource,或 user 問題依賴特定 schema / service,`SELECT 1` 後再執行 identity query,記錄目前 session 的 user、schema、service / database。例如 Oracle 可用 `SELECT USER, SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), SYS_CONTEXT('USERENV','SERVICE_NAME') FROM dual`;其他 DB 使用對應 identity function。
|
|
115
|
+
|
|
116
|
+
### 6. Run Bounded SQL
|
|
117
|
+
|
|
118
|
+
撰寫剛好能回答問題的最小查詢:
|
|
119
|
+
|
|
120
|
+
- 先從 metadata tables 開始,不要一開始就掃 business tables。
|
|
121
|
+
- 使用 `WHERE`、date bounds、primary keys,以及 `LIMIT`/`TOP`/`FETCH FIRST`。
|
|
122
|
+
- 除非 table 很小,或 user 明確要求 raw inspection,否則避免使用 `SELECT *`。
|
|
123
|
+
- 面對大表時,先跑 counts 或 grouped summaries。
|
|
124
|
+
- 如果 query 可能代價很高,先說明風險,再徵求同意後執行。
|
|
125
|
+
- 明確區分 SQL dialect-specific syntax,不要假設 PostgreSQL 語法可以直接套用到 Oracle 或 SQL Server。
|
|
126
|
+
- 明確區分 dialect-specific semantics。只有在已辨識目前 DB 是 Oracle 時,才套用 Oracle 的 empty-string/NULL 規則;其他 DB 依各自語意處理。
|
|
127
|
+
- Oracle 查非空字串時,不要寫 `= ''`、`<> ''`,也不要寫 `TRIM(NVL(col, '')) <> ''`。Oracle 會把 `''` 視為 `NULL`,這類 predicate 容易把原本有值的 rows 全部過濾掉。判斷 trim 後非空時,優先使用 `LENGTH(TRIM(NVL(col, ' '))) > 0`;若只是判斷有無值,可用 `TRIM(col) IS NOT NULL`。
|
|
128
|
+
- 若第一個 bounded inventory query 回傳 0 rows,但依 repo/catalog/context 應有資料,先回頭確認目前 schema / service 是否正確、table/view 是否在當前 namespace 可見,再決定這是 validated empty 還是連錯環境 / authority 不明。
|
|
129
|
+
|
|
130
|
+
### 7. Report Results
|
|
131
|
+
|
|
132
|
+
回報時包含:
|
|
133
|
+
|
|
134
|
+
- DB type and environment, if known.
|
|
135
|
+
- Connection source: config file path, env var names, DSN name, container, or user-provided session values. Redact secrets.
|
|
136
|
+
- SQL statements executed, with sensitive literals removed if needed.
|
|
137
|
+
- Result summary: row count, key rows, anomalies,.
|
|
138
|
+
- Follow-up gaps: missing schema permission, unresolved config placeholder, ambiguous environment, or query not run.
|
|
139
|
+
|
|
140
|
+
最終輸出不要包含 plaintext credentials。
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# DB Client Commands
|
|
2
|
+
|
|
3
|
+
這份 reference 提供使用 native CLI 進行查詢的方式。實際使用時需依 repo 的 DB type、environment、schema、VPN/bastion/container 條件調整。
|
|
4
|
+
|
|
5
|
+
## General Handling
|
|
6
|
+
|
|
7
|
+
- 優先使用 password prompts、wallets、DSN 或 session environment variables,避免把 password 直接放在 command-line arguments。
|
|
8
|
+
- 查詢完成後,清除暫時性的 environment variables。
|
|
9
|
+
- 可以的話,優先使用 read-only users。
|
|
10
|
+
- query files 應維持為暫時用途,不要 commit。
|
|
11
|
+
- logs 與 final answers 中的 credentials 要遮蔽。
|
|
12
|
+
|
|
13
|
+
## Oracle
|
|
14
|
+
|
|
15
|
+
建議使用的 clients: `sqlplus`、Oracle SQLcl `sql`。
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
sqlplus -L /nolog
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
接著在 client session 內連線:
|
|
22
|
+
|
|
23
|
+
```sql
|
|
24
|
+
connect <username>/<password>@//<host>:<port>/<service_name>
|
|
25
|
+
SELECT 1 FROM dual;
|
|
26
|
+
exit
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
實用的 inspection queries:
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
SELECT owner, table_name
|
|
33
|
+
FROM all_tables
|
|
34
|
+
WHERE owner = UPPER('<schema>')
|
|
35
|
+
FETCH FIRST 50 ROWS ONLY;
|
|
36
|
+
|
|
37
|
+
SELECT owner, table_name, column_name, data_type, nullable
|
|
38
|
+
FROM all_tab_columns
|
|
39
|
+
WHERE owner = UPPER('<schema>')
|
|
40
|
+
AND table_name = UPPER('<table_name>')
|
|
41
|
+
ORDER BY column_id;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
較舊的 Oracle versions 可能需要使用 `WHERE ROWNUM <= 50`,而不是 `FETCH FIRST`。
|
|
45
|
+
|
|
46
|
+
## PostgreSQL
|
|
47
|
+
|
|
48
|
+
建議使用的 client: `psql`。
|
|
49
|
+
|
|
50
|
+
```powershell
|
|
51
|
+
$env:PGPASSWORD = "<password>"
|
|
52
|
+
psql -h <host> -p <port> -U <username> -d <database> -c "SELECT 1;"
|
|
53
|
+
Remove-Item Env:\PGPASSWORD
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
實用的 inspection queries:
|
|
57
|
+
|
|
58
|
+
```sql
|
|
59
|
+
SELECT table_schema, table_name
|
|
60
|
+
FROM information_schema.tables
|
|
61
|
+
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
62
|
+
ORDER BY table_schema, table_name
|
|
63
|
+
LIMIT 50;
|
|
64
|
+
|
|
65
|
+
SELECT column_name, data_type, is_nullable
|
|
66
|
+
FROM information_schema.columns
|
|
67
|
+
WHERE table_schema = '<schema>'
|
|
68
|
+
AND table_name = '<table_name>'
|
|
69
|
+
ORDER BY ordinal_position;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## SQL Server
|
|
73
|
+
|
|
74
|
+
建議使用的 client: `sqlcmd`。
|
|
75
|
+
|
|
76
|
+
```powershell
|
|
77
|
+
$env:SQLCMDPASSWORD = "<password>"
|
|
78
|
+
sqlcmd -S <host>,<port> -d <database> -U <username> -Q "SELECT 1;"
|
|
79
|
+
Remove-Item Env:\SQLCMDPASSWORD
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
若使用 Windows authentication:
|
|
83
|
+
|
|
84
|
+
```powershell
|
|
85
|
+
sqlcmd -S <host>,<port> -d <database> -E -Q "SELECT 1;"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
實用的 inspection queries:
|
|
89
|
+
|
|
90
|
+
```sql
|
|
91
|
+
SELECT TOP (50) TABLE_SCHEMA, TABLE_NAME
|
|
92
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
93
|
+
WHERE TABLE_TYPE = 'BASE TABLE'
|
|
94
|
+
ORDER BY TABLE_SCHEMA, TABLE_NAME;
|
|
95
|
+
|
|
96
|
+
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE
|
|
97
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
|
98
|
+
WHERE TABLE_SCHEMA = '<schema>'
|
|
99
|
+
AND TABLE_NAME = '<table_name>'
|
|
100
|
+
ORDER BY ORDINAL_POSITION;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## MySQL And MariaDB
|
|
104
|
+
|
|
105
|
+
建議使用的 clients: `mysql`、`mariadb`。
|
|
106
|
+
|
|
107
|
+
```powershell
|
|
108
|
+
$env:MYSQL_PWD = "<password>"
|
|
109
|
+
mysql --host=<host> --port=<port> --user=<username> --database=<database> --execute="SELECT 1;"
|
|
110
|
+
Remove-Item Env:\MYSQL_PWD
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
實用的 inspection queries:
|
|
114
|
+
|
|
115
|
+
```sql
|
|
116
|
+
SELECT TABLE_SCHEMA, TABLE_NAME
|
|
117
|
+
FROM information_schema.TABLES
|
|
118
|
+
WHERE TABLE_SCHEMA = '<database>'
|
|
119
|
+
ORDER BY TABLE_NAME
|
|
120
|
+
LIMIT 50;
|
|
121
|
+
|
|
122
|
+
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE
|
|
123
|
+
FROM information_schema.COLUMNS
|
|
124
|
+
WHERE TABLE_SCHEMA = '<database>'
|
|
125
|
+
AND TABLE_NAME = '<table_name>'
|
|
126
|
+
ORDER BY ORDINAL_POSITION;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## SQLite
|
|
130
|
+
|
|
131
|
+
建議使用的 client: `sqlite3`。
|
|
132
|
+
|
|
133
|
+
```powershell
|
|
134
|
+
sqlite3 <database_file> "SELECT 1;"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
實用的 inspection commands:
|
|
138
|
+
|
|
139
|
+
```sql
|
|
140
|
+
.tables
|
|
141
|
+
PRAGMA table_info('<table_name>');
|
|
142
|
+
SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view') ORDER BY name LIMIT 50;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## IBM Db2
|
|
146
|
+
|
|
147
|
+
建議使用的 client: `db2`。
|
|
148
|
+
|
|
149
|
+
```powershell
|
|
150
|
+
db2 connect to <database> user <username> using <password>
|
|
151
|
+
db2 -x "SELECT 1 FROM sysibm.sysdummy1"
|
|
152
|
+
db2 connect reset
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
實用的 inspection queries:
|
|
156
|
+
|
|
157
|
+
```sql
|
|
158
|
+
SELECT tabschema, tabname
|
|
159
|
+
FROM syscat.tables
|
|
160
|
+
WHERE type = 'T'
|
|
161
|
+
ORDER BY tabschema, tabname
|
|
162
|
+
FETCH FIRST 50 ROWS ONLY;
|
|
163
|
+
|
|
164
|
+
SELECT colname, typename, nulls
|
|
165
|
+
FROM syscat.columns
|
|
166
|
+
WHERE tabschema = UPPER('<schema>')
|
|
167
|
+
AND tabname = UPPER('<table_name>')
|
|
168
|
+
ORDER BY colno;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## H2
|
|
172
|
+
|
|
173
|
+
H2 常見於 tests 或 local development 中以 embedded 方式使用。優先使用 repo 的 test profile 或 app 提供的 console/tooling。
|
|
174
|
+
|
|
175
|
+
常見的 JDBC URL patterns:
|
|
176
|
+
|
|
177
|
+
```text
|
|
178
|
+
jdbc:h2:mem:<database>
|
|
179
|
+
jdbc:h2:file:<path>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
實用的 inspection query:
|
|
183
|
+
|
|
184
|
+
```sql
|
|
185
|
+
SELECT TABLE_SCHEMA, TABLE_NAME
|
|
186
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
187
|
+
ORDER BY TABLE_SCHEMA, TABLE_NAME
|
|
188
|
+
LIMIT 50;
|
|
189
|
+
```
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Query Safety
|
|
2
|
+
|
|
3
|
+
## Read-Only Default
|
|
4
|
+
|
|
5
|
+
除非 user 明確要求資料修改,否則預設只允許 metadata 與 read-only `SELECT`。如果查詢內容涉及下列操作,必須先停下來確認:
|
|
6
|
+
|
|
7
|
+
- `INSERT`, `UPDATE`, `DELETE`, `MERGE`, `TRUNCATE`
|
|
8
|
+
- `CREATE`, `ALTER`, `DROP`
|
|
9
|
+
- `GRANT`, `REVOKE`
|
|
10
|
+
- 可能修改資料的 stored procedure/function/package calls
|
|
11
|
+
- scheduler/job control、queue dequeue、lock/session kill
|
|
12
|
+
|
|
13
|
+
## Row Limits By Dialect
|
|
14
|
+
|
|
15
|
+
請使用有筆數上限的查詢:
|
|
16
|
+
|
|
17
|
+
```sql
|
|
18
|
+
-- PostgreSQL, MySQL, MariaDB, SQLite, H2
|
|
19
|
+
SELECT <columns>
|
|
20
|
+
FROM <table>
|
|
21
|
+
WHERE <condition>
|
|
22
|
+
LIMIT 50;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```sql
|
|
26
|
+
-- SQL Server
|
|
27
|
+
SELECT TOP (50) <columns>
|
|
28
|
+
FROM <schema>.<table>
|
|
29
|
+
WHERE <condition>;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```sql
|
|
33
|
+
-- Oracle 12c+, IBM Db2
|
|
34
|
+
SELECT <columns>
|
|
35
|
+
FROM <schema>.<table>
|
|
36
|
+
WHERE <condition>
|
|
37
|
+
FETCH FIRST 50 ROWS ONLY;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```sql
|
|
41
|
+
-- Older Oracle
|
|
42
|
+
SELECT <columns>
|
|
43
|
+
FROM <schema>.<table>
|
|
44
|
+
WHERE <condition>
|
|
45
|
+
AND ROWNUM <= 50;
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Oracle Empty String Semantics
|
|
49
|
+
|
|
50
|
+
這一節只在已確認 `db_type`、driver 或 client session 是 Oracle 時適用。不要把這組規則套用到 PostgreSQL、SQL Server、MySQL、MariaDB、SQLite、Db2 或其他 DB。
|
|
51
|
+
|
|
52
|
+
Oracle 會把 `''` 視為 `NULL`。因此 Oracle predicate 對空字串的處理要直接用 `NULL` 語意,不要把 `''` 當成一般字串比較。
|
|
53
|
+
|
|
54
|
+
- 不要用 `= ''`、`<> ''`,也不要用 `TRIM(NVL(<column>, '')) <> ''` 判斷空值或非空值。
|
|
55
|
+
- 判斷 `NULL` / 非 `NULL` 時,使用 `IS NULL` 或 `IS NOT NULL`。
|
|
56
|
+
- 判斷 trim 後是否有內容時,優先使用 `LENGTH(TRIM(NVL(<column>, ' '))) = 0` 或 `> 0`;若只需要確認 trim 後有值,可用 `TRIM(<column>) IS NOT NULL`。
|
|
57
|
+
- 若 query 結果意外為 0 rows,先檢查是否誤用了 Oracle empty-string 語意,再解讀資料是否真的為空。
|
|
58
|
+
|
|
59
|
+
範例:
|
|
60
|
+
|
|
61
|
+
```sql
|
|
62
|
+
-- Avoid in Oracle
|
|
63
|
+
WHERE path_program <> ''
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```sql
|
|
67
|
+
-- Avoid in Oracle even after wrapping with TRIM/NVL
|
|
68
|
+
WHERE TRIM(NVL(path_program, '')) <> ''
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```sql
|
|
72
|
+
-- Prefer when checking for the presence of a trimmed value
|
|
73
|
+
WHERE TRIM(path_program) IS NOT NULL
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
-- Prefer when checking for a non-empty value after trimming
|
|
78
|
+
WHERE LENGTH(TRIM(NVL(path_program, ' '))) > 0
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Safer Investigation Pattern
|
|
82
|
+
|
|
83
|
+
1. 先透過 metadata 確認 schema/table 存在。
|
|
84
|
+
2. 只有在安全的前提下,才檢查大致筆數或精確 count。
|
|
85
|
+
3. 先查 grouped summary,再看 row sample。
|
|
86
|
+
4. 以關鍵欄位查詢範圍較小的 sample。
|
|
87
|
+
5. 依照 user request 加上業務過濾條件。
|
|
88
|
+
|
|
89
|
+
範例:
|
|
90
|
+
|
|
91
|
+
```sql
|
|
92
|
+
SELECT status, COUNT(*) AS row_count
|
|
93
|
+
FROM <schema>.<table>
|
|
94
|
+
WHERE created_at >= <start_date>
|
|
95
|
+
GROUP BY status
|
|
96
|
+
ORDER BY row_count DESC;
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Reporting
|
|
100
|
+
|
|
101
|
+
最終回覆應提供足夠證據,讓結果可被重現,同時避免洩露敏感資訊:
|
|
102
|
+
|
|
103
|
+
- connection source:`src/main/resources/application-dev.yml`、`.env`、`docker-compose.yml`、user-provided session value
|
|
104
|
+
- DB type 與 target environment
|
|
105
|
+
- SQL statements;如果使用了敏感 literal,則改提供摘要化 SQL
|
|
106
|
+
- result rows 或 aggregate summary
|
|
107
|
+
- 不確定之處與 permission gaps
|
|
108
|
+
|
|
109
|
+
不可包含 plaintext password values、token values、帶有憑證資訊的 URL,或任何 private network secrets。
|