Skip to content

Commit aa5b20f

Browse files
committed
perf: improve generate Oracle SQL
1 parent 8952095 commit aa5b20f

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

backend/apps/chat/models/chat_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ class AiModelQuestion(BaseModel):
185185

186186
def sql_sys_question(self, db_type: Union[str, DB], enable_query_limit: bool = True):
187187
_sql_template = get_sql_example_template(db_type)
188-
_base_sql_rules = _sql_template['quot_rule'] + _sql_template['limit_rule'] + _sql_template['other_rule']
189188
_query_limit = get_sql_template()['query_limit'] if enable_query_limit else get_sql_template()['no_query_limit']
189+
_base_sql_rules = _sql_template['quot_rule'] + _query_limit + _sql_template['limit_rule'] + _sql_template['other_rule']
190190
_sql_examples = _sql_template['basic_example']
191191
_example_engine = _sql_template['example_engine']
192192
_example_answer_1 = _sql_template['example_answer_1_with_limit'] if enable_query_limit else _sql_template[
@@ -198,7 +198,7 @@ def sql_sys_question(self, db_type: Union[str, DB], enable_query_limit: bool = T
198198
return get_sql_template()['system'].format(engine=self.engine, schema=self.db_schema, question=self.question,
199199
lang=self.lang, terminologies=self.terminologies,
200200
data_training=self.data_training, custom_prompt=self.custom_prompt,
201-
base_sql_rules=_base_sql_rules, query_limit=_query_limit,
201+
base_sql_rules=_base_sql_rules,
202202
basic_sql_examples=_sql_examples,
203203
example_engine=_example_engine,
204204
example_answer_1=_example_answer_1,

backend/templates/sql_examples/Oracle.yaml

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,41 @@ template:
1010
</rule>
1111
1212
limit_rule: |
13-
<rule>
13+
<rule priority="high">
1414
当需要限制行数时:
1515
1. 12c以下版本必须使用ROWNUM语法
1616
2. 12c+版本推荐使用FETCH FIRST语法
1717
<note>
18-
1. 传统写法:WHERE ROWNUM <= 100
19-
2. 现代写法:FETCH FIRST 100 ROWS ONLY
18+
版本适配:
19+
- Oracle 12c以下:必须使用 WHERE ROWNUM <= N
20+
- Oracle 12c+:推荐使用 FETCH FIRST N ROWS ONLY
2021
</note>
2122
<note>
22-
使用传统 ROWNUM 写法时,若遇到需要分组 GROUP BY 的情况,需要将限制条数的 ROWNUM 写在最外层,不然会影响最后查询出数据的总条数
23+
<strong>重要:ROWNUM必须放在正确的位置,避免语法错误</strong>
24+
1. <strong>单层查询</strong>:ROWNUM直接跟在WHERE子句后
25+
<template>SELECT ... FROM table WHERE conditions AND ROWNUM <= N</template>
26+
2. <strong>多层查询</strong>:ROWNUM只能放在最外层
27+
<template>
28+
SELECT ... FROM (
29+
SELECT ... FROM table WHERE conditions GROUP BY ...
30+
) WHERE ROWNUM <= N -- 正确:在最外层
31+
</template>
32+
3. <strong>禁止的错误写法</strong>:
33+
<error-example>
34+
SELECT ... FROM table
35+
WHERE conditions
36+
GROUP BY ...
37+
ORDER BY ...
38+
WHERE ROWNUM <= N -- 错误:不能有多个WHERE
39+
</error-example>
40+
4. <strong>正确顺序</strong>:WHERE → GROUP BY → HAVING → ORDER BY → ROWNUM
41+
5. <strong>括号位置</strong>:从内层SELECT开始到内层结束都要括起来
42+
<correct>
43+
SELECT ... FROM (
44+
-- 内层完整查询(包含自己的SELECT、FROM、WHERE、GROUP BY、ORDER BY)
45+
SELECT columns FROM table WHERE conditions GROUP BY ... ORDER BY ...
46+
) alias WHERE ROWNUM <= N
47+
</correct>
2348
</note>
2449
</rule>
2550
@@ -87,6 +112,17 @@ template:
87112
GROUP BY "u"."DEPARTMENT"
88113
ORDER BY "department_name" -- 错误:ROWNUM 应当写在最外层,这样会导致查询结果条数比实际数据的数量少
89114
</output-bad>
115+
<output-bad>
116+
SELECT "department_name", "user_count" FROM
117+
SELECT
118+
"u"."DEPARTMENT" AS "department_name",
119+
count(*) AS "user_count"
120+
FROM "PUBLIC"."USERS" "u"
121+
WHERE "u"."status" = 1
122+
GROUP BY "u"."DEPARTMENT"
123+
ORDER BY "department_name"
124+
WHERE ROWNUM <= 100 -- 错误:语法错误,同级内只能有一个WHERE
125+
</output-bad>
90126
<output-good>
91127
SELECT "department_name", "user_count" FROM (
92128
SELECT
@@ -97,7 +133,7 @@ template:
97133
GROUP BY "u"."DEPARTMENT"
98134
ORDER BY "department_name"
99135
)
100-
WHERE ROWNUM <= 100
136+
WHERE ROWNUM <= 100 -- 外层限制(确保最终结果可控)
101137
</output-good>
102138
</example>
103139
</basic-examples>

backend/templates/template.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ template:
77
{data_training}
88
sql:
99
query_limit: |
10-
<rule>
11-
如果用户没有指定数据条数的限制,输出的查询SQL必须加上1000条的数据条数限制。
10+
<rule priority="high">
11+
1. <strong>必须遵守</strong>:所有生成的SQL必须包含数据量限制
12+
2. <strong>默认限制</strong>:1000条(除非用户明确指定其他数量)
1213
</rule>
1314
no_query_limit: |
14-
<rule>
15+
<rule priority="high">
1516
如果没有指定数据条数的限制,则查询的SQL默认返回全部数据
1617
</rule>
1718
system: |
@@ -68,7 +69,6 @@ template:
6869
提问中如果有涉及数据源名称或数据源描述的内容,则忽略数据源的信息,直接根据剩余内容生成SQL
6970
</rule>
7071
{base_sql_rules}
71-
{query_limit}
7272
<rule>
7373
如果生成SQL的字段内有时间格式的字段:
7474
- 若提问中没有指定查询顺序,则默认按时间升序排序

0 commit comments

Comments
 (0)