- contact@verticalserve.com
Stored procedure work usually fails in the least convenient place: after a developer has already translated requirements into SQL, chosen a dialect, wired credentials, and pushed the code somewhere close to the real database. The first compile error sends everyone back into a manual edit-and-retry loop.
The sp-automation-app turns that loop into an InsightWorker app. It
accepts a natural-language request, reads the target database profile from
config.yaml, generates the stored procedure in the correct dialect, validates
syntax, attempts compilation on the configured database, fixes compile errors, retries, and
logs every attempt.
The app does not hardcode a database connection or target
platform. The prompt chooses a configured database profile such as
oracle_db or postgresql_db, and InsightWorker reads the host,
schema, wallet path, retry count, and log path from the app config. Public pages
and logs should always redact secrets.
config.yaml.
Stored procedure automation has two common failure modes. First, generic SQL generation ignores the target dialect, so Oracle PL/SQL, PostgreSQL functions, and SQL Server procedures get blurred together. Second, generated SQL may look plausible but still fail when compiled against the real schema.
This app treats compilation as part of generation. It does not stop at a text artifact. It keeps going until the procedure is syntactically valid for the configured database, or until it reaches the configured retry ceiling and reports what still needs a human decision.
The user describes the procedure goal, target table, database profile, filters, grouping rules, and expected output.
The app loads the requested database profile, retry limit, logging flag, and log
file path from config.yaml.
InsightWorker generates dialect-specific procedure code, including parameters, output cursor or result shape, and comments.
The generated procedure is checked for dialect and structural issues before it is sent to the database compiler.
If compilation fails, the app reads the database error, patches the SQL, and retries until it compiles or hits max attempts.
The final procedure and compile attempts are saved under the app output and log folders for review.
The important production detail is that the app does not bake Oracle, PostgreSQL, schema names, wallet paths, or retry counts into the article logic. It reads those values from app-level config. The example below is intentionally redacted for public use.
That means a prompt can say Use oracle_db or Use postgresql_db, and
the app selects the matching connection profile from config.yaml. The
stored procedure name, table, and business logic come from the prompt and schema context,
not from a hardcoded demo path.
The app also keeps cross-database mappings in a separate mapping file. That gives the generator a structured way to translate common types and functions when the same business logic moves across platforms.
| Mapping area | Example | Production purpose |
|---|---|---|
| Types | NUMBER to NUMERIC, VARCHAR2 to
VARCHAR |
Prevents simple dialect mismatches when generating or porting procedure code. |
| Functions | SYSDATE to CURRENT_TIMESTAMP |
Keeps date/time logic platform-aware instead of relying on generic SQL. |
| Validation | Compile attempt logs and retry status | Separates a generated draft from a procedure proven valid by the target database. |
One reference run asks the app to generate an Oracle ADW procedure that calculates total
rental amount by customer for a specified year using the RENTAL table.
The output is a dialect-specific procedure artifact. In the sample run, the app
generated an Oracle procedure with p_year as input and a
SYS_REFCURSOR output.
The strongest part of this app is not the first draft. It is the loop after the first draft. The compile log shows a booking procedure fail on the first attempt with a PL/SQL syntax error, then compile successfully after the app patched the procedure and retried.
The hardened version added safer conversions for string-stored amount and date fields, explicit NLS date language handling, and exception cleanup for open cursors. That is the practical difference between code generation and production automation.
config.yaml, so Oracle or
PostgreSQL targets are not hardcoded in the app page.max_compile_attempts controls the retry ceiling, preventing endless fix
loops.logs/compile_attempts.log when logging
is enabled.This app does not replace schema design, indexing strategy, performance testing, or business-rule ownership. It accelerates the mechanical path from requirement to compiled procedure. Humans still decide whether the logic is correct, whether it is performant enough for production data volumes, and whether it belongs in the database layer.