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
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
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
Map each job to an Agent job with a T-SQL step. The
WHATblock 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 thesp_add_job,sp_add_jobstepandsp_add_schedulecalls yourself and check them against SSMA's conversion report. https://learn.microsoft.com/sql/ssma/oracle/sql-server-migration-assistant-for-oracle-oracletosqlSchedules need translating by hand. A DBMS_JOB
INTERVALis a date expression, for exampleTRUNC(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.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
SYSDATEwas on local server time. Decide this before you provision. https://learn.microsoft.com/azure/azure-sql/managed-instance/timezones-overviewAgent on Managed Instance has limits:
- Supported step types include T-SQL and SSIS. CmdExec and PowerShell steps are not supported, so any job that ran OS scripts has to move elsewhere (Azure Automation, Data Factory or Logic Apps).
- You can't stop or restart Agent. Notifications go by email through Database Mail only. https://learn.microsoft.com/azure/azure-sql/managed-instance/job-automation-managed-instance
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.
Security context changes. A DBMS_JOB runs as
LOG_USER/SCHEMA_USERwith 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.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
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
mapping_dbms-job--sql-agent-miscore 19.974dispute_dbms-job-deprecated-vs-removedscore 19.209feature_dbms-schedulerscore 18.977pattern_scheduler-jobs-to-azurescore 17.717target_sql-agent-miscore 17.068mapping_tls-1-0-1-1--azure-sql-dbscore 16.489mapping_dbms-scheduler--pg-cronscore 15.811source_oracle-base-dbms-job-19cscore 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
WHATblock): 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]. INTERVALexpression: The syntax doesn't carry over. Rewrite each interval as an equivalent Agent schedule [1].- Failure handling: Replace logic that depended on
BROKENflags 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
- Inventory
DBA_JOBS. On 19c, each DBMS_JOB job also appears inDBA_SCHEDULER_JOBSas aDBMS_JOB$_nrow, 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]. - Convert each job body with SSMA.
- Create the Agent job and its schedule.
- Set up retry and email alerts.
- 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
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
- initial_context on groq · 4,126 chars back
- 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} } } } - 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.SUBMITis transactional — a job disappears if the caller's transaction rolls back — even in 19c. SQL Server Agent job creation (likeDBMS_SCHEDULER.CREATE_JOBand 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.SUBMITrequires the CREATE JOB privilege; without it, submission fails withORA-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
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
- initial_context on groq · 4,126 chars back
- initial_context on kb · 7,679 chars back
- 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} - knowledge_base_read on kb · 7,982 chars back
{ "knowledgeBase": "kb6MdvV3ZA3Q", "paths": [ "feature_migration/scheduler_jobs", "oracle_concepts/terminology" ] } - 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}} } - 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.