mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
perf: improve generate Oracle SQL
This commit is contained in:
@@ -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 @@ class AiModelQuestion(BaseModel):
|
||||
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,
|
||||
|
||||
@@ -10,16 +10,41 @@ template:
|
||||
</rule>
|
||||
|
||||
limit_rule: |
|
||||
<rule>
|
||||
<rule priority="high">
|
||||
当需要限制行数时:
|
||||
1. 12c以下版本必须使用ROWNUM语法
|
||||
2. 12c+版本推荐使用FETCH FIRST语法
|
||||
<note>
|
||||
1. 传统写法:WHERE ROWNUM <= 100
|
||||
2. 现代写法:FETCH FIRST 100 ROWS ONLY
|
||||
版本适配:
|
||||
- Oracle 12c以下:必须使用 WHERE ROWNUM <= N
|
||||
- Oracle 12c+:推荐使用 FETCH FIRST N ROWS ONLY
|
||||
</note>
|
||||
<note>
|
||||
使用传统 ROWNUM 写法时,若遇到需要分组 GROUP BY 的情况,需要将限制条数的 ROWNUM 写在最外层,不然会影响最后查询出数据的总条数
|
||||
<strong>重要:ROWNUM必须放在正确的位置,避免语法错误</strong>
|
||||
1. <strong>单层查询</strong>:ROWNUM直接跟在WHERE子句后
|
||||
<template>SELECT ... FROM table WHERE conditions AND ROWNUM <= N</template>
|
||||
2. <strong>多层查询</strong>:ROWNUM只能放在最外层
|
||||
<template>
|
||||
SELECT ... FROM (
|
||||
SELECT ... FROM table WHERE conditions GROUP BY ...
|
||||
) WHERE ROWNUM <= N -- 正确:在最外层
|
||||
</template>
|
||||
3. <strong>禁止的错误写法</strong>:
|
||||
<error-example>
|
||||
SELECT ... FROM table
|
||||
WHERE conditions
|
||||
GROUP BY ...
|
||||
ORDER BY ...
|
||||
WHERE ROWNUM <= N -- 错误:不能有多个WHERE
|
||||
</error-example>
|
||||
4. <strong>正确顺序</strong>:WHERE → GROUP BY → HAVING → ORDER BY → ROWNUM
|
||||
5. <strong>括号位置</strong>:从内层SELECT开始到内层结束都要括起来
|
||||
<correct>
|
||||
SELECT ... FROM (
|
||||
-- 内层完整查询(包含自己的SELECT、FROM、WHERE、GROUP BY、ORDER BY)
|
||||
SELECT columns FROM table WHERE conditions GROUP BY ... ORDER BY ...
|
||||
) alias WHERE ROWNUM <= N
|
||||
</correct>
|
||||
</note>
|
||||
</rule>
|
||||
|
||||
@@ -87,6 +112,17 @@ template:
|
||||
GROUP BY "u"."DEPARTMENT"
|
||||
ORDER BY "department_name" -- 错误:ROWNUM 应当写在最外层,这样会导致查询结果条数比实际数据的数量少
|
||||
</output-bad>
|
||||
<output-bad>
|
||||
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
|
||||
</output-bad>
|
||||
<output-good>
|
||||
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 -- 外层限制(确保最终结果可控)
|
||||
</output-good>
|
||||
</example>
|
||||
</basic-examples>
|
||||
|
||||
@@ -7,11 +7,12 @@ template:
|
||||
{data_training}
|
||||
sql:
|
||||
query_limit: |
|
||||
<rule>
|
||||
如果用户没有指定数据条数的限制,输出的查询SQL必须加上1000条的数据条数限制。
|
||||
<rule priority="high">
|
||||
1. <strong>必须遵守</strong>:所有生成的SQL必须包含数据量限制
|
||||
2. <strong>默认限制</strong>:1000条(除非用户明确指定其他数量)
|
||||
</rule>
|
||||
no_query_limit: |
|
||||
<rule>
|
||||
<rule priority="high">
|
||||
如果没有指定数据条数的限制,则查询的SQL默认返回全部数据
|
||||
</rule>
|
||||
system: |
|
||||
@@ -68,7 +69,6 @@ template:
|
||||
提问中如果有涉及数据源名称或数据源描述的内容,则忽略数据源的信息,直接根据剩余内容生成SQL
|
||||
</rule>
|
||||
{base_sql_rules}
|
||||
{query_limit}
|
||||
<rule>
|
||||
如果生成SQL的字段内有时间格式的字段:
|
||||
- 若提问中没有指定查询顺序,则默认按时间升序排序
|
||||
|
||||
Reference in New Issue
Block a user