Trae + SQLazy Practice: Breathing New Life into Legacy SQL
I. Introduction
Almost every data team has a piece of "legacy SQL" in their codebase that no one wants to touch. A hundred or even hundreds of lines, with dozens of nested CTEs and window functions nested inside window functions. The person who wrote it has long left the company, comments are almost non-existent, no one dares to modify it, and no one can fully understand it. When a business metric needs to change, the person taking over needs to spend hours figuring out what each subquery does, then spend hours debugging after changes, terrified that changing one line might break the entire logic.
Even with AI programming, things don't improve much. Due to hallucinations, AI can only assist interpretation, and ultimately engineers need to confirm. After interpretation, you just get another document, which may not match over time. Moreover, SQL regenerated by AI based on modified requirements is likely to be completely different from the original, requiring time and effort to re-verify, and adding another piece of'legacy SQL'.
Can we crystallize AI's interpretation results into code that can be both read as documentation and compiled for execution?
This is what SQLazy scripts are for.
AI understands SQL, then translates it into structured, readable, and verifiable SQLazy (*.nspl) scripts. For handover and inheritance, you only need to use this script, and the final SQL can be compiled and generated by SQLazy at any time. SQLazy's compilation engine does not depend on large models — deterministic inputs always produce deterministic outputs. When modification needs arise in the future, you just need to modify and debug based on this readable SQLazy script, then recompile to get new SQL.
This article attempts to use Trae as the "brain," responsible for understanding SQL semantics, breaking down business logic, and generating SQLazy step-by-step scripts; then use the SQLazy IDE as the "execution layer," responsible for syntax validation, step-by-step debugging, and final code compilation. Together they form a closed loop of "AI interpretation + human review + deterministic engine compilation," bringing legacy SQL back to life.
II. Tools' Roles and Capabilities
1. Trae: The "Brain" for Understanding and Translation
Trae is an AI programming tool that can be used both as a standalone IDE and as a VS Code-style editor. Here, Trae plays three roles:
(1) Automatic loading of project knowledge base. The project deploys global specification files (plan.md) that declare the output format specification for SQLazy scripts (three-column tab-separated, single function per step), hard constraints (reserved word handling, cross-step reference rules), and loading paths for function and feature documentation. When the user enters "/sqlazy-plan" Trae automatically inherits all the above rules without needing to redeclare them.
(2) Structured four-step output. Trae is constrained to output solutions following four steps: capability review, requirement decomposition, function matching, and code implementation — rather than directly giving conclusions. This forced output process ensures the reviewability of solutions; the rationale for each step is clearly visible. The final output is a structured SQLazy script, not a chunk of hard-to-read SQL.
(3) Proactive clarification of requirement boundaries. Facing complex requirements, Trae will proactively raise key questions, such as: How should the date range be defined? How should null values be handled? Is the grouping key unique? This avoids AI "self-righteously" assuming prerequisites.
2. SQLazy: The "Hands" for Execution and Verification
SQLazy is a structured data computing tool with a dedicated IDE for writing and executing .nspl scripts. In simple terms, it breaks complex business logic into readable "operation instructions," each completing one data processing step. The SQLazy IDE receives .nspl scripts output by Trae and provides three guarantees:
(1) Single-step semantics are clear, with low audit barriers. Taking "stock consecutive rise days" as an example, the .nspl script only needs 5 steps: filter → sort → segment → summarize count → summarize max. Reading the entire script is like reading a business operation checklist.
(2) Step-by-step execution for rapid problem localization. In the IDE, you can run each step individually and view intermediate results in real time. Once a step's output doesn't meet expectations, you can immediately locate the specific logic error.
(3) One script, multi-database compilation. After verification, one-click compilation generates standard SQL for mainstream databases like MySQL, PostgreSQL, Oracle, etc., without needing to rewrite for different databases.
III. Operational Process
3.1 Environment Preparation
The project adopts the following standard directory structure:
project_root/
├── plan.md # Global specification: format standards, loading paths
├── sqlazy-plan.md # Command entry: /sqlazy-plan trigger, inherits all rules from plan.md
├── nspl/ # Delivery directory: SQLazy scripts stored here
├── function/ # Function reference documentation (auto-loaded)
└── action/ # Action reference documentation (auto-loaded)
After creating a new project in Trae, copy the sqlazy-plan.md, plan.md files and the function and action directories from the LLM directory under the SQLazy installation directory to the project root directory.
3.2 Trigger Method
Use the "/sqlazy-plan" command in the Trae chat box to trigger the task, followed by a complete business requirement description.
3.3 Verification and Correction
This is the most critical step in the entire chain:
1. Construct a small amount of representative test data and manually calculate expected results
2. Run the script step by step in the SQLazy IDE and compare intermediate results with expected values
3. When issues are found, you can directly modify the script or feed it back to Trae to regenerate
After verification passes, compile to generate SQL for the corresponding database. This step is very simple and won't be mentioned in the practical examples below.
IV. Hands-on Cases
The following five cases are presented in order of "from simple to complex, from smooth to frustrated." The first three cases demonstrate different difficulty levels of translation processes, the fourth case records the real journey of multiple corrections, and the last case is a typical failure case where "the script runs but results are wrong," showing the blind spots when AI understands business logic.
Case 1: Segmented Cumulative by Condition — Passed First Try
Original SQL functionality: The id field of the data table exam_tbl is used for sorting, the logic field is used for condition judgment, and val is used for segmented accumulation. A new calculated column output is added: when logic==true, output is set to 1; otherwise, output accumulates and takes the value of the previous row's output + val.
[Operation] type the following into the Trae chat box:
/sqlazy-plan Convert the following SQL statement to SQLazy script:
with table1 as (
SELECT *, countif(logic) over win1 as logic_run
FROM exam_tbl
window win1 as (order by id rows between unbounded preceding and current row)
)
SELECT *,
sum(val) over win2 as sum_over,
sum(if(logic,1,val)) over win2 as output
from table1
window win2 as (partition by logic_run order by id rows between unbounded preceding and current row)
[Trae's SQL Analysis]
Trae analyzed: This SQL has two layers of windows. The first layer window win1 is sorted by id, using countif(logic) for cumulative counting — every time a row with logic=true is encountered, logic_run increments by 1, thereby dividing data into multiple 'segments'. The second layer window win2 is within the logic_run segment, sorted by id to separately sum val (sum_over) and sum the conditional expression if(logic,1,val) (output). Translating to NSPL: countif can be replaced by a two-step process of 'condition → accumulate', and partitioned accumulation uses 'accumulate + partition'.
[Generated SQLazy Script]
VariableName |
Anchor |
Statement |
t1 |
exam_tbl |
sort id |
t2 |
compute if(logic then 1 else 0), as logic_flag |
|
t3 |
compute logic_flag, cum, as logic_run |
|
t4 |
compute if(logic then 1 else val), as logic_val |
|
t5 |
compute val, cum, as sum_over; partition logic_run |
|
t6 |
compute logic_val, cum, as output; partition logic_run |
|
t7 |
derive id, logic, val, logic_run, sum_over, output |
This is a "textbook-style" translation — the SQL window function semantics are clear, and SQLazy's"accumulate"and"partition" features naturally correspond to them. Trae generated it once and it passed in the SQLazy IDE without corrections.
Case 2: Conditional Grouping — Passed After One Syntax Correction
Original SQL functionality: The data table test_table_mm has fields id, split, cust, date_column, amount, etc. Conditional grouping needs to be performed: group by the first two fields id and split. If the date_column within the group has no duplicates, keep the record with the most recent date and replace amount with the sum of amount for the group; if dates within the group have duplicates, regroup the records by cust, keep the record with the most recent date in the current subgroup, and replace amount with the sum of amount for the current subgroup.
[Operation] type the following into the Trae chat box:
/sqlazy-plan Convert the following SQL statement to SQLazy script:
SELECT id,
split,
cust,
date_column,
CASE num_cust
WHEN 1
THEN total_amount
ELSE total_cust_amount
END AS amount
FROM (
SELECT t.*,
COUNT(DISTINCT CASE rnk WHEN 1 THEN cust END)
OVER (PARTITION BY id, split) AS num_cust
FROM (
SELECT t.*,
DENSE_RANK() OVER (PARTITION BY id, split ORDER BY date_column DESC) AS rnk,
SUM(amount) OVER (PARTITION BY id, split) AS total_amount,
SUM(amount) OVER (PARTITION BY id, split, cust) AS total_cust_amount
FROM test_table_mm t
) t
WHERE rnk = 1
)
[Trae's SQL Analysis]
Trae analyzed: Need to first partition by id and split, use ranking to find the row with the maximum date_column (rnk=1). Simultaneously calculate two sums: total_amount grouped by id+split, and total_cust_amount grouped by id+split+cust three-key. After filtering rows with rnk=1, count the unique cust num_cust in each id+split group. Finally use a conditional function to determine: if num_cust=1 take total_amount, otherwise take total_cust_amount.
[Generated SQLazy Script]
VariableName |
Anchor |
Statement |
t2 |
test_table_mm |
rank date_column desc;chinese rank; partition id, split; as rnk |
t3 |
compute amount, sum, as total_amount; partition id, split |
|
t4 |
compute amount, sum, as total_cust_amount; partition id, split, cust |
|
t5 |
filter (rnk = 1) |
|
t6 |
compute cust, icount, as num_cust; partition id, split |
|
t7 |
compute if(num_cust = 1 then total_amount else total_cust_amount), as amount |
|
t8 |
derive id, split, cust, date_column, amount |
[Syntax Correction]
During runtime, SQLazy reported an error: in the "rank" statement at line t2, the "option"parameter was initially written as"chinese rank"which is not a valid SQLazy keyword. The ranking function parameter in SQLazy should be"dense"(indicating Chinese ranking, where tied ranks are not skipped). After correcting"chinese rank"to"dense" in the first line of code, the script ran successfully.
Case 3: Backtracking Initial Date with Sum — Passed After One Syntax Correction
Original SQL functionality: The data table table_name records the inbound quantity of specific date plans and the cumulative inventory after inbound. Now we need to use the cumulative inventory to backtrack to the initial date — the day with zero or negative inventory — and fill in the inbound quantity UPDATED_QTY and original inventory UPDATED_CUSTQTY after each day's consumption.
[Operation] type the following into the Trae chat box:
/sqlazy-plan Convert the following SQL statement to SQLazy script:
SELECT t.*,
LEAST(
GREATEST(
COALESCE(
SUM(
CASE WHEN needdate < TRUNC(to_date('2024-02-26')) + 1 THEN qty END
) OVER (PARTITION BY item, loc ORDER BY needdate DESC) - custqty,
qty
),
0
),
qty
) AS updated_qty,
CASE
WHEN needdate > TRUNC(to_date('2024-02-26'))
THEN NULL
WHEN SUM(
CASE WHEN needdate < TRUNC(to_date('2024-02-26')) + 1 THEN qty END
) OVER (
PARTITION BY item, loc
ORDER BY needdate DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) >= custqty
THEN NULL
ELSE GREATEST(
custqty
- SUM(
CASE WHEN needdate < TRUNC(to_date('2024-02-26')) + 1 THEN qty END
) OVER (PARTITION BY item, loc ORDER BY needdate DESC),
0
)
END AS updated_custqty
FROM table_name t
[Trae's SQL Analysis]
Trae analyzed: This is an inventory calculation logic that 'uses sum to backtrack to the initial date'. Need to first sort, conditionally filter, partition and accumulate, then compare the previous row's cumulative value (prev_cumulative_qty) with custqty, and rewrite qty and custqty in three scenarios: if accumulation is insufficient, clear qty and deduct custqty; if accumulation is exactly right, take the difference; if accumulation exceeds, keep qty and clear custqty. Conditional functions need nested processing.
[Generated SQLazy Script]
VariableName |
Anchor |
Statement |
t2 |
table_name |
sort needdate desc |
t3 |
compute if(needdate < date(2024-02-26) + 1 then qty else 0), as filtered_qty |
|
t4 |
compute filtered_qty, cum, as cumulative_qty; partition item, loc |
|
t5 |
compute cumulative_qty[-1], as prev_cumulative_qty |
|
t6 |
compute if(nvl(cumulative_qty - custqty, qty) < 0 then 0, nvl(cumulative_qty - custqty, qty) > qty then qty; else nvl(cumulative_qty - custqty, qty)), as updated_qty |
|
t7 |
compute if(needdate > date(2024-02-26) then null, prev_cumulative_qty >= custqty then null; else if(custqty - cumulative_qty < 0 then 0; else custqty - cumulative_qty)), as updated_custqty |
|
t8 |
derive append updated_qty, updated_custqty |
[Syntax Correction]
Runtime error: the date constants in lines t3 and t7 were written without quotes as date(2024-02-26). SQLazy's date function requires the date parameter to be a string constant, which must be enclosed in double quotes. After correcting date(2024-02-26) to date("2024-02-26") in the code, the script ran successfully.
Case 4: Time Interval Aggregation — Passed After Multiple Corrections
Original SQL functionality: The data table tmstmp has two columns dt and payload, storing time-series data with records spaced several seconds apart. Now we need to group and aggregate every minute, summarizing 5 minutes of data each time. For example, if 3 records are generated in the 1st, 2nd, and 3rd seconds, data for minutes 1-5, 2-6, and 3-7 are summarized respectively.
[Operation] type the following into the Trae chat box:
/sqlazy-plan Convert the following SQL statement to SQLazy script:
SELECT
[From], DATEADD(MINUTE, 1, [To]) [To], payload
FROM (
SELECT
dt, MIN(dt) OVER(ORDER BY dt ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) [From],
dt [To], SUM(payload) OVER(ORDER BY dt ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) payload
FROM (
SELECT
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, dt), 0) dt,
SUM(payload) payload
FROM #tmstmp
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, dt), 0)
) q
) q
WHERE DATEDIFF(MINUTE, [From], [To]) > 3
[Trae's SQL Analysis]
Trae analyzed: The inner layer first truncates dt to minute-level and performs GROUP BY summation to get the payload per minute; the middle layer uses a 5-row sliding window (4 PRECEDING to CURRENT ROW) to take MIN(dt) within the window as From, current dt as To, and SUM(payload) as payload; the outer layer filters DATEDIFF(From,To)>3 and adds 1 minute to To. Translating to SQLazy: '5-row window' can be implemented using 'row reference [-4] to current row'; when data is sorted, MIN(dt) equals mt[-4] (the earliest time row).
[Generated SQLazy Script]
VariableName |
Anchor |
Statement |
t1 |
tmstmp |
compute datetime(dt; precision minute) as mt |
t2 |
summarize payload total as payload; group mt |
|
t3 |
t2 |
sort mt |
t4 |
compute mt[-5] as from_t, mt[-1] as to_t, nvl(payload[-5],0)+payload[-4]+payload[-3]+payload[-2]+payload[-1]+payload as payload |
|
t5 |
filter (interval(from from_t, to to_t; minute)> 3) |
|
t6 |
derive from_t, to_t + 1/1440 as to_t, payload |
[Multiple Corrections Process]
This case best demonstrates the complete closed loop of "AI first draft + human feedback + iterative correction." Trae made several types of errors, each representative:
Error Correction Records
Round |
Error Symptom |
Root Cause |
Correction Method |
Round 1 |
Parameter[] value setting error |
Misused "total"as aggregation function keyword; should be"sum" in SQLazy |
Change "total"to"sum" |
Round 2 |
Value [from] has no matching parameter |
Interval function mistakenly included parameter names "from" "to"; SQLazy requires omitting these |
Remove parameter names, write as positional parameters: interval(from_t, to_t; minute) |
Round 3 |
from_t null value rows not filtered out |
When from_t is null, interval function returns null |
Change to: filter (from_t not empty) |
Round 4 |
Unrecognized expression: from_t not empty |
"not empty" is not valid SQLazy syntax |
Change "not empty" to "notnull" |
Round 5 |
Time interval only 4 minutes |
Window offset error; mt[-1] and mt[-5] caused window to miss one row |
Change to mt (current row) and mt[-4] (previous 4 rows) |
Round 6 |
to_t + 1/1440 value unchanged after operation |
Float 1/1440 has precision loss; time addition not effective |
Use SQLazy's"elapse" function: (to_t elapse 1 minute) |
[Final Script]
VariableName |
Anchor |
Statement |
t1 |
tmstmp |
compute datetime(dt; precise minute), as mt |
t2 |
t1 |
summarize payload sum as agg_payload; group mt |
t3 |
t2 |
sort mt |
t4 |
compute mt, as to_t; mt[-4], as from_t; nvl(agg_payload[-4], 0)+ nvl(agg_payload[-3], 0)+ nvl(agg_payload[-2], 0)+ nvl(agg_payload[-1], 0) + agg_payload, as payload |
|
t5 |
filter (from_t notnull) |
|
t6 |
derive from_t, (to_t elapse 1 minute) as to_t, payload |
Six rounds of correction sounds like a lot, but each round of feedback is as simple as "paste the error message to Trae," and Trae can mostly locate and fix the issue in one round. This is the value of the "AI interpretation + human review + small data verification" process: AI does the work, humans check, and when errors occur, paste them back for AI to fix.
Case 5: Time Window Statistics — Script Runs But Results Are Wrong
Original SQL functionality: The data table main has time and value fields. The time field is the time, and the time interval is sometimes greater than 1 minute. Now we need to divide data into one-minute windows, fill in missing windows, and calculate 4 values for each window: start_value (the last record of the previous window), end_value (the last record of the current window), min (minimum value of the current window), max (maximum value of the current window). The start_value for the first minute uses the first record of the current window; if a window's data is missing, use the last record of the previous window instead (same as the current window's start_value).
[Operation] type the following into the Trae chat box:
/sqlazy-plan Convert the following SQL statement to SQLazy script:
with overview as (
SELECT
distinct on (a.time) a.id, a.time, b.time as "end", a.value,
date_trunc('minute', a.time) as minute_start,
date_trunc('minute', b.time) as minute_end
FROM
main a
left join
main b
on
a."time"<b."time" and a.id = b.id
order by
a.time, b.time asc
),
overview2 as (
select
id, value, true as backfill,
date_trunc('minute', "end") as time,
date_trunc('minute', "end") as minute
from
overview
where
minute_start <> minute_end
UNION ALL
select
id, time, value, false as backfill,
date_trunc('minute', time) as minute
from
overview
),
overview3 as (
select
*
from
overview2
UNION ALL (
Select
distinct on (a.missingminute)
c.id,
a.missingminute as time,
a.missingminute as minute,
c.value,
true as backfill
from (
SELECT
date_trunc('minute', time.time) as missingminute
FROM
generate_series((select min(minute) from overview2),(select max(minute) from overview2),'1 minute'::interval) time
left join (
select distinct
minute
from
overview2
) b
on
date_trunc('minute', time) = b.minute
where
b.minute isnull
) a
left join
main c
on
a.missingminute > c.time
order by
a.missingminute,
c.time desc
)
order by
time
)
select
t1.id,
t1.minute as minute_start,
t1.minute + interval '1 minute' as minute_end,
t1.backfill as start_backfill,
t1.start,
t2.end,
coalesce(t3.min, t1.start) as min,
coalesce(t3.max, t1.start) as max
from
(select distinct on (id, minute) id, minute, value as start, backfill from overview3 order by id, minute, time asc) t1
left join
(select distinct on (id, minute) id, minute, value as end from overview3 order by id, minute, time desc) t2 on t1.id = t2.id and t1.minute = t2.minute
left join
(select id, minute, min(value) min, max(value) max from overview2 group by id,minute) t3 on t1.id = t3.id and t1.minute = t3.minute
[Trae's SQL Analysis]
Trae analyzed: This SQL's overview uses a self-join to find the next time point, overview2 splits records spanning minute boundaries and marks backfill, overview3 uses generate_series to fill missing minutes, and finally outputs start, end, min, max for each minute. Trae translated this understanding into a 23-step SQLazy script.
[Generated SQLazy Script (Key Steps Excerpt)]
VariableName |
Anchor |
Statement |
t1 |
main |
sort 'time' |
t2 |
compute # as id, 'time'[1] as next_time |
|
t3 |
compute datetime('time'; precision minute) as mt, datetime(next_time; precision minute) as mt_end |
|
t4 |
filter (mt <> mt_end) |
|
t5 |
derive id, mt_end as 'time', value, true as backfill, mt_end as mt |
|
t6 |
t3 |
derive id, 'time', value, false as backfill, mt |
t7 |
t6 |
set union; t5 |
... |
(intermediate steps omitted, total 23 steps) |
|
t9 |
t7 |
summarize value min as vmin, value max as vmax; group by mt |
t23 |
derive filled_id as id, mt as minute_start, ... nvl(vmin, filled_start) as vmin, nvl(vmax, filled_start) as vmax |
[Problem: Script Runs But Results Are Wrong]
After multiple rounds of syntax corrections, it finally ran successfully, but when comparing with test data, the results didn't match expectations. Trae had a semantic deviation in understanding the SQL during translation.
[Deep Analysis of Trae's Understanding Deviation]
Deviation Analysis
Deviation |
Trae's Understanding |
Actual SQL Logic |
Deviation 1: Mistook "id" as row number |
Calculated "# as id" (row number) in line t2 |
a.id in SQL is a real data column in the main table, a "sequence/grouping key" (multiple records with the same id form a time series). SQL groups and deduplicates by (id, minute) throughout. Using row number as id completely loses the "sequence by id" semantics, causing all sequences to be mixed in the same minute bucket for aggregation. |
Deviation 2: Used "next row" instead of "next event of same id" |
Used 'time'[1] in line t2 — only the next row after sorting by time, without id constraint |
SQL's self-join condition is a.time<b.time AND a.id=b.id — filter by id first before taking the next record. After sorting multi-id data by time, adjacent rows likely belong to different ids, so the'next event of another id'is treated as the'next event of this id,' generating incorrect backfill rows. |
Deviation 3: "Previous value leakage" in min/max |
Directly aggregated min/max from overview2 |
SQL's overview2 mixes'previous value continuation backfill rows'with'real events', and the final query's t3 directly aggregates min/max from overview2 — causing 'previous value continuation values' to leak into the extreme value statistics. |
[Lesson Learned]
This case reveals an important fact: AI can mechanically "translate" SQL syntax, but may not accurately understand the business intent behind SQL. When the SQL itself has "semantic mixing" in its design (e.g., overview2 contains both previous value continuation rows and real events, and aggregates extreme values from them), AI will faithfully carry this "design flaw" into SQLazy, causing incorrect results. This situation cannot be fixed by "pasting errors" alone — because the script doesn't error — it just"calculates incorrectly."
V. Summary: Process, Experience, and Boundaries
1. Standard Process for Solving Legacy SQL
Through the practical operation of the above five cases, we can extract a standard process for "converting legacy SQL to SQLazy":
Step 1: Initiate command. Send the SQL code to Trae, with the attached "/sqlazy-plan Convert the following SQL statement to SQLazy script" command.
Step 2: Generate first draft. Trae outputs the initial SQLazy script following a four-step process (capability review → requirement decomposition → function matching → code implementation).
Step 3: Test and verify. Import test data in the SQLazy IDE, run the script step by step, and compare intermediate results with expected values.
Step 4: Feedback and correct. If there are syntax or logic errors, feed the error message back to Trae for correction. Repeat until it runs correctly.
Step 5: Compile and deliver. After verification passes, one-click compilation generates SQL for the target database for production use.
Save this SQLazy script for future modification and handover, without needing to keep the hard-to-understand SQL script.
2. Experience Summary
Through the operation of these cases, we can draw a relatively optimistic but sober conclusion:
Most SQL statements can be correctly translated to readable, easily verifiable SQLazy code. From Case 1 passed first try, to Cases 2 and 3 passed after one correction, to Case 4 passed after 6 rounds of correction, these cases cover typical scenarios like segmented conditions, conditional grouping, inventory backtracking, and time interval aggregation. Trae ultimately delivered correct answers. SQLazy scripts'"single-step semantics are clear" feature allows business logic originally buried in SQL nesting to be exposed to sunlight, significantly lowering the barrier for human review.
But there are a few very complex SQL statements where Trae may deviate in understanding business logic, leading to incorrect results. Case 5 is a typical counterexample — the script doesn't error, but the results are wrong.
3. Advanced Strategy for Handling Complex SQL
Facing complex SQL like Case 5, simply "sending SQL to Trae for translation" is no longer sufficient. A more reliable approach is:
First, let Trae analyze the SQL's functionality step by step to assist engineers in reading and understanding SQL. For example, you can ask Trae:"Please analyze what query requirements this SQL statement completes"— let Trae explain what overview, overview2, and overview3 each do layer by layer, and what the final output is. The purpose of this step is to let humans (not AI) first understand the SQL's true intent.
After understanding the SQL's true intent, submit the"requirement description"(rather than the original SQL) to Trae, letting it write the SQLazy script based on the requirement description. This avoids the trap of"SQL itself has design flaws, and AI faithfully carries the flaws over"— because you describe"what should be done,"not"how SQL does it," allowing AI to use more straightforward algorithms to write the SQLazy script.
Ultimately, AI is a productivity amplifier, not an "automatic vending machine" that replaces human judgment. Where should legacy SQL go? The answer is not "throw it to AI for automatic translation," but a three-way collaboration of "humans understand intent, AI converts scripts, engines verify execution." Only then can legacy SQL transform from a "time bomb no one dares to touch" into a "business asset readable by everyone."
SPL Official Website 👉 https://www.esproc.com
SPL Feedback and Help 👉 https://www.reddit.com/r/esProcSPL
SPL Learning Material 👉 https://c.esproc.com
SPL Source Code and Package 👉 https://github.com/SPLWare/esProc
Discord 👉 https://discord.gg/sxd59A8F2W
Youtube 👉 https://www.youtube.com/@esProc_SPL