From aa5b20fa4d4bd832b546f4242d47969110cffeea Mon Sep 17 00:00:00 2001 From: ulleo Date: Mon, 24 Nov 2025 18:57:08 +0800 Subject: [PATCH] perf: improve generate Oracle SQL --- backend/apps/chat/models/chat_model.py | 4 +- backend/templates/sql_examples/Oracle.yaml | 46 +++++++++++++++++++--- backend/templates/template.yaml | 8 ++-- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/backend/apps/chat/models/chat_model.py b/backend/apps/chat/models/chat_model.py index 544f771d..5e7f0136 100644 --- a/backend/apps/chat/models/chat_model.py +++ b/backend/apps/chat/models/chat_model.py @@ -185,8 +185,8 @@ class AiModelQuestion(BaseModel): def sql_sys_question(self, db_type: Union[str, DB], enable_query_limit: bool = True): _sql_template = get_sql_example_template(db_type) - _base_sql_rules = _sql_template['quot_rule'] + _sql_template['limit_rule'] + _sql_template['other_rule'] _query_limit = get_sql_template()['query_limit'] if enable_query_limit else get_sql_template()['no_query_limit'] + _base_sql_rules = _sql_template['quot_rule'] + _query_limit + _sql_template['limit_rule'] + _sql_template['other_rule'] _sql_examples = _sql_template['basic_example'] _example_engine = _sql_template['example_engine'] _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 return get_sql_template()['system'].format(engine=self.engine, schema=self.db_schema, question=self.question, lang=self.lang, terminologies=self.terminologies, data_training=self.data_training, custom_prompt=self.custom_prompt, - base_sql_rules=_base_sql_rules, query_limit=_query_limit, + base_sql_rules=_base_sql_rules, basic_sql_examples=_sql_examples, example_engine=_example_engine, example_answer_1=_example_answer_1, diff --git a/backend/templates/sql_examples/Oracle.yaml b/backend/templates/sql_examples/Oracle.yaml index 5281f597..b7293465 100644 --- a/backend/templates/sql_examples/Oracle.yaml +++ b/backend/templates/sql_examples/Oracle.yaml @@ -10,16 +10,41 @@ template: limit_rule: | - + 当需要限制行数时: 1. 12c以下版本必须使用ROWNUM语法 2. 12c+版本推荐使用FETCH FIRST语法 - 1. 传统写法:WHERE ROWNUM <= 100 - 2. 现代写法:FETCH FIRST 100 ROWS ONLY + 版本适配: + - Oracle 12c以下:必须使用 WHERE ROWNUM <= N + - Oracle 12c+:推荐使用 FETCH FIRST N ROWS ONLY - 使用传统 ROWNUM 写法时,若遇到需要分组 GROUP BY 的情况,需要将限制条数的 ROWNUM 写在最外层,不然会影响最后查询出数据的总条数 + 重要:ROWNUM必须放在正确的位置,避免语法错误 + 1. 单层查询:ROWNUM直接跟在WHERE子句后 + + 2. 多层查询:ROWNUM只能放在最外层 + + 3. 禁止的错误写法: + + SELECT ... FROM table + WHERE conditions + GROUP BY ... + ORDER BY ... + WHERE ROWNUM <= N -- 错误:不能有多个WHERE + + 4. 正确顺序:WHERE → GROUP BY → HAVING → ORDER BY → ROWNUM + 5. 括号位置:从内层SELECT开始到内层结束都要括起来 + + SELECT ... FROM ( + -- 内层完整查询(包含自己的SELECT、FROM、WHERE、GROUP BY、ORDER BY) + SELECT columns FROM table WHERE conditions GROUP BY ... ORDER BY ... + ) alias WHERE ROWNUM <= N + @@ -87,6 +112,17 @@ template: GROUP BY "u"."DEPARTMENT" ORDER BY "department_name" -- 错误:ROWNUM 应当写在最外层,这样会导致查询结果条数比实际数据的数量少 + + SELECT "department_name", "user_count" FROM + SELECT + "u"."DEPARTMENT" AS "department_name", + count(*) AS "user_count" + FROM "PUBLIC"."USERS" "u" + WHERE "u"."status" = 1 + GROUP BY "u"."DEPARTMENT" + ORDER BY "department_name" + WHERE ROWNUM <= 100 -- 错误:语法错误,同级内只能有一个WHERE + SELECT "department_name", "user_count" FROM ( SELECT @@ -97,7 +133,7 @@ template: GROUP BY "u"."DEPARTMENT" ORDER BY "department_name" ) - WHERE ROWNUM <= 100 + WHERE ROWNUM <= 100 -- 外层限制(确保最终结果可控) diff --git a/backend/templates/template.yaml b/backend/templates/template.yaml index 8f5ea680..7e15db29 100644 --- a/backend/templates/template.yaml +++ b/backend/templates/template.yaml @@ -7,11 +7,12 @@ template: {data_training} sql: query_limit: | - - 如果用户没有指定数据条数的限制,输出的查询SQL必须加上1000条的数据条数限制。 + + 1. 必须遵守:所有生成的SQL必须包含数据量限制 + 2. 默认限制:1000条(除非用户明确指定其他数量) no_query_limit: | - + 如果没有指定数据条数的限制,则查询的SQL默认返回全部数据 system: | @@ -68,7 +69,6 @@ template: 提问中如果有涉及数据源名称或数据源描述的内容,则忽略数据源的信息,直接根据剩余内容生成SQL {base_sql_rules} - {query_limit} 如果生成SQL的字段内有时间格式的字段: - 若提问中没有指定查询顺序,则默认按时间升序排序