New to Kestra?
Use blueprints to kickstart your first workflows.
Find Oracle objects left INVALID after a dependency change, recompile them with ALTER COMPILE behind a dry-run gate, then re-read dba_objects to confirm.
Oracle marks a schema object INVALID when something it depends on changes. Alter a table, replace a view, change a type. Every view, package, procedure, function or trigger built on top of it is flagged INVALID in dba_objects. Oracle recompiles an invalid object on first use, but that first use can be a user request that pays the compile cost or hits a genuine break hidden since the DDL ran.
This blueprint finds those objects before a user does. It reads dba_objects for the schemas you name, recompiles each flagged object with ALTER ... COMPILE, then reads dba_objects again and fails the run if anything is still INVALID.
This blueprint was created by zkasuran.
| Object type in dba_objects | Statement used to recompile |
|---|---|
VIEW, PROCEDURE, FUNCTION, TRIGGER, PACKAGE, TYPE, MATERIALIZED VIEW |
ALTER <type> "owner"."name" COMPILE |
PACKAGE BODY |
ALTER PACKAGE "owner"."name" COMPILE BODY |
TYPE BODY |
ALTER TYPE "owner"."name" COMPILE BODY |
Recompile runs in two passes. A package body can stay invalid on the first pass only because its spec compiled later in the same pass, so a second pass over the same set clears anything whose failure was ordering. An object still invalid after both passes has a real break, usually a column or dependency that was dropped or renamed. The run fails so a human looks at it.
audit (io.kestra.plugin.jdbc.oracle.Query, read-only) reads dba_objects for the
owners in object_owners where status is INVALID, limited to recompilable object
types. It returns the exact ALTER ... COMPILE for each.fixes (io.kestra.plugin.core.output.OutputValues) deduplicates those statements.
summary logs the invalid objects.route (io.kestra.plugin.core.flow.If):alert posts the list to Slack.remediate_gate runs only when auto_remediate is true and dry_run is false.remediate and remediate_second (io.kestra.plugin.core.flow.Loop,
concurrencyLimit: 1) run each ALTER ... COMPILE in turn, twice. Serial on
purpose, so interdependent objects do not compile against each other at once.reaudit reads dba_objects again. verify_result fails the run through
remediation_failed if any object is still INVALID, otherwise remediated
logs the count returned to VALID.errors posts to Slack if the flow fails for any reason, including an object that
could not be recompiled.The usual recompile is a one-off script a DBA keeps in a drawer. Kestra runs it on a
schedule, scopes it to the schemas you own, posts the invalid objects to Slack, applies
the recompile only behind auto_remediate and dry_run, one statement at a time, then
proves the result by reading dba_objects again. Every run keeps its logs, so you can see
when objects went invalid and what fixed them.
On Kestra 2.0.5 OSS against Oracle Database Free 23ai (gvenzl/oracle-free, service
FREEPDB1), with a local HTTP sink standing in for Slack. The test schema APP held a
table T1 and four objects built on its name column: a view V1, a procedure P1, a
package body PKG1 and a trigger TRG1.
| Run | Setup and inputs | Result |
|---|---|---|
| 1 | all objects VALID, defaults | 0 invalid, clean branch, SUCCESS |
| 2 | ALTER TABLE T1 MODIFY name, defaults (dry_run: true) |
4 invalid detected and posted to Slack, no change, SUCCESS. dba_objects still showed 4 |
| 3 | same break, auto_remediate: true, dry_run: true |
Same report, Slack said no change applied, dba_objects still 4. The dry_run gate held |
| 4 | same break, auto_remediate: true, dry_run: false |
Recompiled, reaudit found 0, SUCCESS. dba_objects went from 4 to 0 |
| 5 | ALTER TABLE T1 DROP COLUMN name, auto_remediate: true, dry_run: false |
4 objects could not compile against the dropped column, reaudit still 4, the run FAILED and the errors block alerted Slack |
Runs 1 and 2 are the proof the check can fail: the same audit returned 0 against the healthy schema and 4 against the broken one. Run 4 is the before and after, 4 down to 0, read from dba_objects by sqlplus not only from the Kestra log.
jdbc:oracle:thin:@//host:1521/service).dba_objects (SELECT_CATALOG_ROLE or SELECT ANY DICTIONARY) and recompile the objects it finds. Recompiling another schema's objects
needs ALTER ANY PROCEDURE, ALTER ANY TRIGGER and the matching privileges, which a
DBA role already carries. A user recompiling only its own objects needs none of those.ORACLE_PASSWORD: the database password. It is the default for the password input.SLACK_WEBHOOK_URL: used by alert and the errors block.SECRET_.| Input | Default | Purpose |
|---|---|---|
jdbc_url |
jdbc:oracle:thin:@//localhost:1521/FREEPDB1 |
The Oracle instance to check |
username |
SYSTEM |
The database user |
password |
{{ secret('ORACLE_PASSWORD') }} |
The database password |
object_owners |
[APP] |
Schema owners whose objects are checked |
auto_remediate |
false |
Allow ALTER ... COMPILE |
dry_run |
true |
Must be false for a recompile to run |
ORACLE_PASSWORD and SLACK_WEBHOOK_URL secrets.jdbc_url and username, then list the schemas to check in object_owners.auto_remediate: true and dry_run: false.daily trigger, which always runs in safe mode.UTL_RECOMP.RECOMP_SERIAL for large schemas.