Skip to content

Commit 1abad08

Browse files
jaguarliujaguarliu
authored andcommitted
feat:oracle 数据库测试支持
1 parent d6c01f6 commit 1abad08

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from sqlalchemy.sql import text
2+
from .base import BaseInspector
3+
from sqlalchemy.engine import reflection
4+
from urllib.parse import quote_plus
5+
6+
class OracleInspector(BaseInspector):
7+
"""Oracle元数据获取实现"""
8+
9+
def __init__(self, host: str, port: int, database: str,
10+
username: str, password: str, schema_name: str = None, **kwargs):
11+
super().__init__(host, port, database, username, password, schema_name)
12+
self.schema_name = username.upper() # Oracle模式名通常与用户名一致[3,8](@ref)
13+
14+
def build_conn_str(self, host: str, port: int, database: str,
15+
username: str, password: str) -> str:
16+
# 使用cx_Oracle驱动,支持SID或Service Name[6,8](@ref)
17+
return (
18+
f"oracle+cx_oracle://{quote_plus(username)}:{quote_plus(password)}"
19+
f"@{host}:{port}/?service_name={database}"
20+
)
21+
22+
def get_table_names(self, inspector: reflection.Inspector) -> list[str]:
23+
return inspector.get_table_names(schema=self.schema_name) # 需指定schema[3](@ref)
24+
25+
def get_table_comment(self, inspector: reflection.Inspector,
26+
table_name: str) -> str:
27+
# 查询ALL_TAB_COMMENTS视图[3,5](@ref)
28+
with self.engine.connect() as conn:
29+
sql = text("""
30+
SELECT COMMENTS
31+
FROM ALL_TAB_COMMENTS
32+
WHERE OWNER = :owner
33+
AND TABLE_NAME = :table_name
34+
""")
35+
return conn.execute(sql, {
36+
'owner': self.schema_name,
37+
'table_name': table_name
38+
}).scalar() or ""
39+
40+
def get_column_comment(self, inspector: reflection.Inspector,
41+
table_name: str, column_name: str) -> str:
42+
# 查询ALL_COL_COMMENTS视图[3](@ref)
43+
with self.engine.connect() as conn:
44+
sql = text("""
45+
SELECT COMMENTS
46+
FROM ALL_COL_COMMENTS
47+
WHERE OWNER = :owner
48+
AND TABLE_NAME = :table_name
49+
AND COLUMN_NAME = :column_name
50+
""")
51+
return conn.execute(sql, {
52+
'owner': self.schema_name,
53+
'table_name': table_name,
54+
'column_name': column_name
55+
}).scalar() or ""
56+
57+
def normalize_type(self, raw_type: str) -> str:
58+
# 标准化Oracle类型(如去除精度信息)[3,5](@ref)
59+
return raw_type.split('(')[0].split('%')[0].upper()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{# Oracle专用模板 #}
2+
{% extends "base_prompt.jinja" %}
3+
4+
{% block optimization_rules %}
5+
1. 索引优化策略:
6+
- 优先创建复合索引覆盖WHERE+SELECT字段
7+
- 对高频查询字段建立函数索引
8+
- 大数据量表使用位图索引
9+
2. 查询优化规范:
10+
- 使用绑定变量避免硬解析
11+
- 分区表查询必须指定分区键
12+
- 关联查询驱动表记录量需最小
13+
3. 执行计划控制:
14+
- 强制走索引使用/*+ INDEX(table_name index_name) */
15+
- 避免全表扫描的FILTER操作
16+
4. 特殊语法要求:
17+
- 时间范围使用TO_DATE()显式转换
18+
- 分页查询使用ROWNUM伪列
19+
{% endblock %}
20+
21+
{% block validation_rules %}
22+
1. 统计信息验证:
23+
- 自动检查LAST_ANALYZED时间,超过7天提示更新
24+
2. 执行计划验证:
25+
- 通过DBMS_XPLAN检查ACCESS_PREDICATES
26+
- 确保INDEX RANGE SCAN优于TABLE ACCESS FULL
27+
3. 性能基线检查:
28+
- WHERE条件字段必须有统计直方图
29+
- 多表关联必须存在连接条件索引
30+
{% endblock %}
31+
32+
{% block example_section %}
33+
## 输出示例:
34+
SELECT /*+ INDEX(emp emp_dept_idx) */
35+
e.employee_id AS "工号",
36+
(e.salary * 1.1) AS "调整薪资",
37+
TO_CHAR(e.hire_date, 'YYYY-MM-DD') AS "入职日期"
38+
FROM
39+
employees e
40+
INNER JOIN
41+
departments d ON e.department_id = d.department_id
42+
WHERE
43+
e.job_id = 'IT_PROG'
44+
AND d.location_id IN (1700, 1800)
45+
AND e.hire_date BETWEEN TO_DATE('2020-01-01', 'YYYY-MM-DD') AND SYSDATE
46+
ORDER BY
47+
e.hire_date DESC
48+
FETCH FIRST 100 ROWS ONLY;
49+
{% endblock %}

0 commit comments

Comments
 (0)