The Legacy Obituaries

Case q01 · version-scope

We are on Oracle 19c and use DBMS_JOB for nightly batches. Moving to Azure SQL Managed Instance — what happens to those jobs?

Expected: DBMS_JOB is deprecated (Oracle recommends DBMS_SCHEDULER); on SQL MI the equivalent is SQL Server Agent jobs; schedules and PL/SQL bodies must be rewritten in T-SQL; answer must state the deprecation release.

No tools

The model alone, answering from memory.
larger model · 1 turn · 24 s · 16.5k in / 2.4k out

✗ verdict ✗ grounded ✓ cited

Grader: Implies 19c deprecation; uncited specifics like 16 retries, timezone.

Answer

Verdict: Your DBMS_JOB jobs will not move over automatically. You have to rebuild each one, and on Azure SQL Managed Instance the natural target is SQL Server Agent, which Managed Instance supports and keeps running for you. The PL/SQL each job runs goes through normal code conversion. The job definitions themselves (schedule, owner, retry behaviour) need to be rebuilt as a separate piece of work.

Key facts

  1. Take an inventory first. In 19c, Oracle has deprecated DBMS_JOB and runs those jobs through DBMS_SCHEDULER under the hood. So query both views:

    SELECT job, log_user, schema_user, what, interval, next_date, broken, failures FROM dba_jobs;
    SELECT job_name, job_action, repeat_interval FROM dba_scheduler_jobs WHERE job_name LIKE 'DBMS_JOB$%';
    

    Oracle 19c upgrade notes: https://docs.oracle.com/en/database/oracle/oracle-database/19/upgrd/deprecated-features-oracle-database-19c.html

  2. Map each job to an Agent job with a T-SQL step. The WHAT block becomes a call to the converted stored procedure. SSMA for Oracle (SQL Server Migration Assistant) converts the PL/SQL, but I'm not sure how much of the job setup it rebuilds for you. Plan on scripting the sp_add_job, sp_add_jobstep and sp_add_schedule calls yourself and check them against SSMA's conversion report. https://learn.microsoft.com/sql/ssma/oracle/sql-server-migration-assistant-for-oracle-oracletosql

  3. Schedules need translating by hand. A DBMS_JOB INTERVAL is a date expression, for example TRUNC(SYSDATE)+1+2/24. Agent uses fixed daily, weekly or monthly schedules, so simple nightly jobs map easily. Expressions like "last business day" or "next run is X hours after the last one finished" need either an Agent schedule plus a check inside the procedure, or a different design.

  4. Time zones differ. Agent schedules run in the Managed Instance's time zone. That zone is chosen when the instance is created, defaults to UTC, and can't be changed later. A job set for "02:00" will shift if Oracle SYSDATE was on local server time. Decide this before you provision. https://learn.microsoft.com/azure/azure-sql/managed-instance/timezones-overview

  5. Agent on Managed Instance has limits:

  6. Failure handling works differently. When a DBMS_JOB fails, Oracle retries it with increasing waits (up to 16 attempts) and then marks it BROKEN. Agent has per-step retry attempts and intervals plus on-failure actions. Set these on purpose and add alerting, or failures may go unnoticed.

  7. Security context changes. A DBMS_JOB runs as LOG_USER/SCHEMA_USER with that session's NLS settings. In Agent, set the job owner and the step's database or user context. Watch for date and number formats that the procedures relied on implicitly.

  8. Jobs that call application code with DBMS_JOB.SUBMIT at runtime (fire-and-forget async work) are a separate problem. Rewrite those using Service Broker, a queue table polled by an Agent job, or something outside the database such as Functions or Data Factory.

Recommended approach: inventory the jobs and sort them into three groups: simple nightly T-SQL, OS/script-dependent, and dynamically submitted. Script the Agent jobs as code in source control. Run old and new side by side during cutover, and disable the Oracle jobs (DBMS_JOB.BROKEN) at the final switchover so nothing runs twice.

Keyword search

BM25 over the same 446 documents: top 8 passages pasted in, one pass, references not followed.
larger model · 1 turn · 12 s · 19.4k in / 1.2k out

✗ verdict ✓ grounded ✗ cited

Grader: Good mapping but omits deprecation release; Scheduler barely mentioned.

8 keyword-search passages
  1. mapping_dbms-job--sql-agent-mi score 19.974
  2. dispute_dbms-job-deprecated-vs-removed score 19.209
  3. feature_dbms-scheduler score 18.977
  4. pattern_scheduler-jobs-to-azure score 17.717
  5. target_sql-agent-mi score 17.068
  6. mapping_tls-1-0-1-1--azure-sql-db score 16.489
  7. mapping_dbms-scheduler--pg-cron score 15.811
  8. source_oracle-base-dbms-job-19c score 15.7
Answer

Verdict: The jobs don't migrate automatically. Each one has to be rebuilt as a SQL Server Agent job on Managed Instance: convert its PL/SQL body to a T-SQL stored procedure, then run it from an Agent job step on a schedule. Most nightly batches are simple interval jobs, so this is usually a partial but manageable conversion [1][4].

How the pieces map

  • Job body (the WHAT block): Use SSMA to convert it into a T-SQL stored procedure. Then create an Agent job with a T-SQL step that calls the procedure [1].
  • INTERVAL expression: The syntax doesn't carry over. Rewrite each interval as an equivalent Agent schedule [1].
  • Failure handling: Replace logic that depended on BROKEN flags with Agent step retry and notification settings [1]. Notifications are email only, through Database Mail. Only one mail profile is allowed, and it must have a fixed name [4][5].
  • Transactional submit: In Oracle, a job submitted inside a transaction that rolls back disappears. Agent doesn't work that way, so re-test any job that relies on this [1][8].
  • Time zones: Record each job's time zone explicitly. Oracle jobs can carry a session time zone [4].

Limits of Agent on Managed Instance [1][5]

  • It doesn't support CmdExec, PowerShell, Analysis Services, merge replication or queue reader steps.
  • It has no proxies, alerts, pager or NetSend notifications, idle-CPU schedules, or multi-server (MSX/TSX) administration.
  • Agent is always on, and you can't change its settings.
  • Any job that runs external programs needs Azure Functions or Data Factory instead [5].
  • Schedules set to fire when Agent starts also fire after every failover [4].

Conflict in the sources: Passage [4] says Agent on Managed Instance can run operating-system and PowerShell steps. Passages [1] and [5] say CmdExec and PowerShell steps aren't supported. Treat them as unsupported until you've checked this against current Microsoft documentation.

Steps

  1. Inventory DBA_JOBS. On 19c, each DBMS_JOB job also appears in DBA_SCHEDULER_JOBS as a DBMS_JOB$_n row, so don't count those twice [1][8]. Check whether any of these jobs are really data refreshes or purges; those may belong in a pipeline tool instead [4].
  2. Convert each job body with SSMA.
  3. Create the Agent job and its schedule.
  4. Set up retry and email alerts.
  5. Re-test anything that depends on transactional submit.

Timing: DBMS_JOB isn't removed in 19c. It's deprecated but still works through 26ai. If DBMS_JOB.SUBMIT fails with ORA-27486, the cause is the new requirement for the CREATE JOB privilege. So the migration drives the timeline, not an Oracle removal [2][8].

Source: ORACLE-BASE, https://oracle-base.com/articles/19c/dbms_job-jobs-converted-to-dbms_scheduler-jobs-19c

Sanity Context · GROQ

The agent with the GROQ endpoint: schema, joins, Portable Text.
smaller model · 4 turns · 31 s · 39.0k in / 2.6k out

✓ verdict ✓ grounded ✓ cited

Grader: States 12.2 deprecation, DBMS_SCHEDULER replacement, Agent rewrite; well cited.

3 tool calls
  1. initial_context on groq · 4,126 chars back
  2. groq_query on groq · 8,400 chars back
    *[_type=="oracleFeature" && (name match "DBMS_JOB*" || slug.current match "*dbms-job*" || slug.current match "*dbms_job*")]{
      _id, name, slug, category, introducedIn, deprecatedIn, desupportedIn, oracleReplacement, reviewStatus,
      "mappings": *[_type=="mapping" && oracleFeature._ref == ^._id]{
        _id, fidelity, effort, rationale, appliesToOracleVersions,
        "azureTarget": azureTarget->{name, service, tierNotes},
        "sources": sources[]->{title, url},
        "caveats": *[_type=="caveat" && mapping._ref == ^._id]{
          _id, severity, statement, appliesTo, firsthand,
          "evidence": evidence->{title, url}
        }
      }
    }
  3. groq_query on groq · 2,879 chars back
    *[_type=="dispute" && (claimA._ref in ["caveat_dbms-job-community-removed","caveat_dbms-job-still-works","caveat_dbms-job-create-job-privilege-19c","caveat_dbms-job-upgrade-converts-jobs"] || claimB._ref in ["caveat_dbms-job-community-removed","caveat_dbms-job-still-works","caveat_dbms-job-create-job-privilege-19c","caveat_dbms-job-upgrade-converts-jobs"])]{
      title, whatDisagrees, resolution,
      "claimA": claimA->{statement, "src": evidence->title},
      "claimB": claimB->{statement, "src": evidence->title},
      "resolvedBy": resolvedBy->{title,url}
    }
Answer

Verdict: On Oracle 19c → Azure SQL Managed Instance, DBMS_JOB maps with partial fidelity to SQL Server Agent on Managed Instance — the batch logic survives once converted, but transactional-submit and OS-level behaviors do not carry over.

Scoped facts

Feature status (Oracle 19c): DBMS_JOB was deprecated in 12.2 (introduced pre-11.2); it is not desupported. In 19c and later, Oracle's replacement is DBMS_SCHEDULER, and each DBMS_JOB.SUBMIT call transparently creates a paired DBMS_SCHEDULER job (DBMS_JOB$_n); jobs are auto-converted on upgrade, with a mapping recorded in scheduler$_dbmsjob_map. — ORACLE-BASE: DBMS_JOB jobs converted to DBMS_SCHEDULER jobs in Oracle Database 19c, Mike Dietrich: DBMS_JOB behavior change in Oracle 19c during upgrade

Mapping → Azure SQL Managed Instance (applies to 11.2–23ai, incl. 19c): SQL Server Agent is available on every Managed Instance tier, always running, and cannot be disabled (settings are read-only). It covers running the converted PL/SQL-turned-T-SQL job steps on a schedule. Effort rated M. — T-SQL differences between SQL Server and Azure SQL Managed Instance, Automation in Azure SQL overview

What doesn't carry over:

  • Transactional submit semantics: DBMS_JOB.SUBMIT is transactional — a job disappears if the caller's transaction rolls back — even in 19c. SQL Server Agent job creation (like DBMS_SCHEDULER.CREATE_JOB and Elastic Jobs) commits immediately, so any code that relied on conditional job submission inside a transaction needs redesign. (Severity: minor) — Connor McDonald: DBMS_JOB - the joy of transactions
  • Interval expression syntax becomes an Agent schedule (conversion work required).
  • Agent on Managed Instance lacks CmdExec steps, proxies, and alerts — relevant if any nightly batch shells out to OS-level code.
  • On 19c/21c/23ai specifically: calling DBMS_JOB.SUBMIT requires the CREATE JOB privilege; without it, submission fails with ORA-27486 (severity: major) — this is the usual cause of "DBMS_JOB stopped working" reports, not removal. — ORACLE-BASE

Dispute on the record

"Did DBMS_JOB stop working in 19c?"

  • Claim A (ORACLE-BASE): DBMS_JOB is deprecated but functional in 19c+; legacy calls are wrapped by the Scheduler.
  • Claim B (Ask TOM community thread): A poster reported DBMS_JOB submission "not working anymore" after a 12.1→19.8 upgrade.
  • Resolution: Both are compatible — the real cause is the new CREATE JOB privilege requirement (ORA-27486 if missing), not package removal. The package remains deprecated-but-functional through 26ai. For your Azure migration, the practical consequence is unchanged either way: job bodies must be re-homed to SQL Server Agent (Managed Instance, your target), Elastic Jobs (Azure SQL Database), or pg_cron (PostgreSQL Flexible Server) — the timeline isn't forced by any removal. Resolved by: DBMS_JOB (PL/SQL Packages and Types Reference 19c)

Bottom line for your nightly batches: audit both DBA_JOBS and DBA_SCHEDULER_JOBS before migrating (per Mike Dietrich's guidance above), confirm none of the jobs depend on rollback-on-error submission semantics or OS shell-outs, then re-implement as SQL Server Agent jobs on Managed Instance.

GROQ + Knowledge Base

The agent with both endpoints.
smaller model · 7 turns · 39 s · 73.5k in / 3.3k out

✓ verdict ✓ grounded ✓ cited

Grader: Complete: 12.2 deprecation, Scheduler, Agent mapping, T-SQL conversion; cited.

6 tool calls
  1. initial_context on groq · 4,126 chars back
  2. initial_context on kb · 7,679 chars back
  3. groq_query on groq · 933 chars back
    *[_type=="oracleFeature" && (slug.current match "*job*" || slug.current match "*scheduler*" || name match "*DBMS_JOB*" || name match "*Scheduler*")]{_id, name, "slug":slug.current, category, introducedIn, deprecatedIn, desupportedIn, oracleReplacement}
  4. knowledge_base_read on kb · 7,982 chars back
    {
     "knowledgeBase": "kb6MdvV3ZA3Q",
     "paths": [
      "feature_migration/scheduler_jobs",
      "oracle_concepts/terminology"
     ]
    }
  5. groq_query on groq · 7,195 chars back
    *[_type=="mapping" && oracleFeature->slug.current in ["dbms-job","dbms-scheduler"] && azureTarget->service=="azure-sql-mi"]{
      _id,
      "feature": oracleFeature->name,
      "target": azureTarget->name,
      fidelity, effort, rationale, appliesToOracleVersions,
      "sources": sources[]->{title,url},
      "caveats": *[_type=="caveat" && references(^._id)]{severity, statement, appliesTo, firsthand, "evidence": evidence->{title,url}}
    }
  6. groq_query on groq · 2,722 chars back
    *[_type=="dispute" && (claimA._ref in ["caveat_dbms-job-community-removed","caveat_dbms-job-create-job-privilege-19c","caveat_dbms-job-still-works","caveat_dbms-job-upgrade-converts-jobs"] || claimB._ref in ["caveat_dbms-job-community-removed","caveat_dbms-job-create-job-privilege-19c","caveat_dbms-job-still-works","caveat_dbms-job-upgrade-converts-jobs"])]{title, "claimA": claimA->statement, "claimApub": claimA->evidence->publisher, "claimB": claimB->statement, "claimBpub": claimB->evidence->publisher, whatDisagrees, resolution, "resolvedBy": resolvedBy->{title,url}}
Answer

Verdict

Your DBMS_JOB nightly batches will keep running through the upgrade path, but they don't move to Azure SQL Managed Instance as-is — the job bodies get re-homed to SQL Server Agent, and you should treat this as a scheduled, moderate-effort (M) rewrite, not a lift-and-shift. Fidelity is rated partial, not exact.

Scoped facts

Status on Oracle 19c: DBMS_JOB is deprecated (since 12.2) but still functional in 19c — Oracle wraps it: each DBMS_JOB.SUBMIT creates a paired DBMS_SCHEDULER job (DBMS_JOB$_n), and existing jobs are auto-converted during upgrade with the mapping recorded in scheduler$_dbmsjob_map. It is not desupported; Oracle's replacement is DBMS_SCHEDULER. — ORACLE-BASE: DBMS_JOB jobs converted to DBMS_SCHEDULER jobs in Oracle Database 19c, Mike Dietrich: DBMS_JOB behavior change in Oracle 19c during upgrade

Caveat (major) — CREATE JOB privilege: From 19c, schemas calling DBMS_JOB.SUBMIT must hold the CREATE JOB privilege or submissions fail with ORA-27486. Applies to 19c/21c/23ai. — ORACLE-BASE

Azure SQL Managed Instance mapping (DBMS_JOB → SQL Server Agent): Fidelity partial, effort M, applies to Oracle 11.2 through 23ai. Agent runs T-SQL job steps on schedules, which covers the same ground once PL/SQL is converted, but two things don't carry over: (1) DBMS_JOB's transactional submit semantics (a job submitted inside a rolled-back transaction disappears — Agent has no equivalent), and (2) the interval expression syntax, which must become an Agent schedule. Agent on Managed Instance also lacks CmdExec steps, proxies, and alerts. — T-SQL differences between SQL Server and Azure SQL Managed Instance, Automation in Azure SQL overview

Additional Agent limitations on Managed Instance (major caveat): No CmdExec, PowerShell, Analysis Services, merge replication, or Queue Reader job steps; no proxies, alerts, pager/NetSend notifications, idle-CPU schedules, or multi-server (MSX/TSX) administration. Email requires a single Database Mail profile named AzureManagedInstance_dbmail_profile. Agent is always running and cannot be disabled. — T-SQL differences between SQL Server and Azure SQL Managed Instance

How-to guidance: Inventory both DBA_JOBS and DBA_SCHEDULER_JOBS (since 19c auto-converts). Classify by type (PL/SQL block, procedure, external script, chain), schedule complexity, and dependencies. A converted PL/SQL procedure job becomes a T-SQL step calling the converted procedure; a chain becomes a multi-step job with on-success/on-failure branching; an OS/external job either accepts Agent's OS-step restrictions or moves to Azure Functions/Automation. Record time zones explicitly — Oracle jobs can carry a session time zone, while SQL Agent on MI runs in UTC. If a job's sole purpose is moving/refreshing data, use Azure Data Factory instead of the database scheduler. — [Move DBMS_SCHEDULER and DBMS_JOB jobs to SQL Agent, Elastic Jobs or pg_cron](knowledge base entry feature_migration/scheduler_jobs, source: Dataset)

Dispute on the record

"Did DBMS_JOB stop working in 19c?" — an Ask TOM thread (publisher: community) claims DBMS_JOB submission "stopped working" after a 12.1→19.8 upgrade — Ask TOM thread. Countered by community documentation (ORACLE-BASE) stating DBMS_JOB remains deprecated-but-functional, with such failures actually caused by the new CREATE JOB privilege requirement, not removal. Resolution (per DBMS_JOB — PL/SQL Packages and Types Reference 19c): Both are compatible — the privilege change, not removal, explains most "not working" reports; the package remains deprecated and functional through 26ai. For an Azure move the practical consequence is unchanged either way: job bodies must be re-homed to SQL Server Agent (MI), Elastic Jobs (Azure SQL DB), or pg_cron (PostgreSQL) — the timeline just isn't forced by removal.

All casesq02 →