Feed aggregator

Calling AI from SQL Server 2025 can lock everyone out of your on-prem instance

Yann Neuhaus - Mon, 2026-10-12 02:22

With SQL Server 2025, Microsoft lets the database engine call an AI model by itself. sp_invoke_external_rest_endpoint sends an HTTPS request straight from T-SQL, to Azure OpenAI or to any other REST service, so an embedding or a completion no longer needs application code in between.

But what happens under heavy pressure, when hundreds of sessions make that call at the same moment and the model takes its time to answer? I ran this scenario on SQL Server 2025 and on Azure SQL Database, with the same procedure and the same load script. The two platforms do not react the same way at all.

100 sessions calling a 30-second endpointSQL Server 2025Azure SQL Database, 2 vCoresSQL Server 2025 with Resource GovernorCalls sent to the endpoint at once1002222What happens to the othersnothing holds them backrefused at once, error 10928queued, all served after 150 sWorker threads held10022100

The documentation of the procedure describes a cap at 10% of the worker threads. That is not what I measured. Azure SQL Database does cap the calls in my tests, but at 15% of its workers: 22 calls at 2 vCores, 45 at 4 vCores, 30 on a Standard S3. SQL Server 2025 has no cap at all, and the rest of this post shows what happens without it.

The lab

The on-premises setup has three parts, all on one virtual machine (Windows Server 2022, 2 vCPUs): a load generator, a SQL Server 2025 Standard instance, and a small HTTPS endpoint that answers after the delay given in the URL.

The call is wrapped in a procedure, so that every session runs exactly the same thing:

CREATE OR ALTER PROCEDURE dbo.CallSlowAi @delay int, @timeout smallint = 230
AS
BEGIN
    DECLARE @url nvarchar(400) = CONCAT(N'https://<YOUR_VM>:8443/?delay=', @delay);
    DECLARE @ret int, @resp nvarchar(max);
    EXEC @ret = sp_invoke_external_rest_endpoint @url = @url, @method = 'POST',
         @payload = N'{"input":"hello"}', @timeout = @timeout, @response = @resp OUTPUT;
    RETURN @ret;
END

The load generator is a PowerShell function that opens N connections without pooling, sends EXEC dbo.CallSlowAi @delay = 30 on all of them at the same moment, and records for each session the elapsed time and the error number. One process, so the client itself does not slow the VM down.

Before measuring SQL Server, I called the endpoint directly with 200 parallel requests: they all came back in 30.6 seconds. The endpoint is not the bottleneck.

On-premises: no limit, until the workers run out

A worker thread is what SQL Server uses to execute a request: one request running, at least one worker busy. The instance has a fixed pool of them, set by max worker threads; with the default setting on this 2-vCPU machine, that is 512. When they are all taken, new work waits with the THREADPOOL wait type, and that includes logging in, because a login needs a worker too (see my previous blog about this wait type).

Three words matter here, and their numbers should not be added together. A session is a connection. When it runs a request, the request is split into one or more tasks, and each task needs a worker thread to run. A simple call like ours is one task, so one worker; a parallel query would take several. The worker counts I quote also include SQL Server’s own background tasks: about 45 workers on this idle instance. A wait type, on the other hand, is counted per task, whoever owns it.

A session waiting for the endpoint reports the HTTP_EXTERNAL_CONNECTION wait type and keeps its worker thread for the whole wait: every waiting call added one worker to that baseline.

With 300 sessions, SQL Server sent everything at once. I counted 300 TCP connections from sqlservr.exe to port 8443, and all calls returned together:

ErrorNumber : 0
Sessions    : 300
MinSec      : 30.2
MaxSec      : 34.5

With 600 sessions, the instance has only 512 worker threads to give. 510 connections were open at the same time, and the calls finished in two groups:

Finished after (s)   Sessions
30                   193
40                   316
50                     1
60                    90

The first 509 calls left immediately, one per available worker. The last 91 did not wait for the endpoint: they waited for a worker. No error was raised at any point, and nothing held the calls back.

What the rest of the instance sees

I measured the saturation itself during an earlier run of the same 600 sessions, with HTTP/2 still enabled on the endpoint (see below). From the dedicated admin connection:

active_workers  queued_tasks
556             154

-------------------------------------

wait_type                  n
HTTP_EXTERNAL_CONNECTION   513
THREADPOOL                 154

At that moment an ordinary sqlcmd connection failed:

Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login timeout expired.
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Unable to complete login process due to delay in prelogin response.

The admin connection kept answering, and the instance recovered by itself once the calls completed. KILL also works at once on a waiting session (error 596 on the client side).

HTTP/2 changes the shape, not the outcome

HTTP.sys, which hosts my test endpoint, offers HTTP/2 by default. In that mode SQL Server opened 6 TCP connections instead of one per call, and only 100 calls were in flight per host name. The same 300 sessions then finished in three waves:

Finished after (s)   Sessions
30                   100
60                   100
90                   100

The queued sessions show the same HTTP_EXTERNAL_CONNECTION wait and hold a worker while they queue, so the pool empties just as well: the 556 workers above were measured in this mode. The queue has a second effect. @timeout keeps running while a call waits its turn. With a 30-second endpoint and @timeout = 45, the first 100 calls succeeded and the 100 queued ones failed after 45.5 seconds with error 31629, The external rest endpoint execution exceeded the timeout value, although the endpoint was answering normally.

Turning HTTP/2 off on the endpoint removes that queue. I disabled it in HTTP.sys (EnableHttp2Tls and EnableHttp2Cleartext set to 0, then a reboot) and replayed the same load:

300 sessions, 30-second endpointHTTP/2HTTP/1.1TCP connections opened by SQL Server6300Calls in flight at once100300Last call returns after90 s34.5 s

The waves are gone and so are the timeouts caused by the queue. It is not a fix for the instance, though. Each call still holds a worker, the 600-session run at the top of this section was made in HTTP/1.1, and the endpoint now receives every call at once. With a real AI provider you also do not choose the protocol: the server does.

I did not capture the HTTP/2 negotiation, so I cannot say which side sets the figure of 100. What the two modes show together is that SQL Server applies no cap of its own.

But the documentation says 10%?

The page of the procedure is marked as applying to SQL Server 2025, Azure SQL Database, Azure SQL Managed Instance and SQL database in Microsoft Fabric. Its throttling section reads:

The number of concurrent connections to external endpoints done via sp_invoke_external_rest_endpoint are capped to 10% of worker threads, with a maximum of 150 workers.

It adds that a call made beyond the limit raises error 10928. With 512 worker threads, I expected about 51 calls to pass and the others to fail. I got neither the cap nor the error, on RTM as on CU9.

The next sentence of that section gives a hint: it speaks of a single database and of an elastic pool, two notions that only exist in Azure SQL Database. So I ran the same test there.

Azure SQL Database: 22 calls, then an error

Azure SQL Database only calls endpoints from a closed list of Azure services, so the slow endpoint becomes an Azure Function. The database is a single Azure SQL Database in Switzerland North. I started on the vCore model, General Purpose serverless on standard-series (Gen5) hardware with 2 vCores maximum, then scaled the same database to 4 vCores, and finally to Standard S3 in the DTU model. The function runs on the Consumption plan, Node.js 22, in the same region. The procedure is the same, with the URL of the function, and the load script only changes its connection string.

Before any load, the governance view of the database already shows a dedicated limit:

SELECT primary_group_max_workers, primary_group_max_outbound_connection_workers
FROM sys.dm_user_db_resource_governance;
primary_group_max_workers  primary_group_max_outbound_connection_workers
150                        22

I stated my bet before running the load: 22 successes, 78 errors. Result for 100 sessions calling a 30-second endpoint:

ErrorNumber  Sessions  Finished after (s)
0            22        30
10928        78        0
Resource ID : 4. The outbound connection worker limit for the database is 22 and has been reached.

The 78 rejected sessions got their answer immediately, which leaves the database 128 of its 150 workers for everything else, whatever the endpoint does.

Two remarks on this test. The ratio is 15%, not the documented 10%. At 2 vCores the database has 150 workers and a limit of 22. I scaled it to 4 vCores: 300 workers, a limit of 45, and the same load gave 45 successes and 55 errors. In the DTU model, a Standard S3 shows 200 workers and a limit of 30. This is one database, in one region, read on three service objectives and load-tested on two. The ratio could differ on other tiers, hardware generations or Hyperscale, and Microsoft may change it: treat 15% as what I observed, not as a rule. On the endpoint side I needed to do a small adjustment as well: an Azure Function on the Consumption plan served only 100 concurrent requests per instance until I raised maxConcurrentRequests in host.json. A direct test of 200 parallel requests took 62.8 seconds before the change and 30.4 after.

The same limit on-premises, with Resource Governor

SQL Server 2025 exposes nothing comparable. On CU9, sys.dm_user_db_resource_governance does not exist, no system column deals with outbound connections, and the only related configuration option is the on/off switch external rest endpoint enabled.

What SQL Server does have is Resource Governor, and a workload group can limit its number of concurrent requests. I created a group with the Azure value and sent the sessions of the load generator into it through their application name:

USE master;
GO
CREATE WORKLOAD GROUP AiCalls WITH (GROUP_MAX_REQUESTS = 22) USING [default];
GO
CREATE FUNCTION dbo.RgClassifier() RETURNS sysname WITH SCHEMABINDING
AS
BEGIN
    RETURN CASE WHEN APP_NAME() = N'AiLoad' THEN N'AiCalls' ELSE N'default' END;
END
GO
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.RgClassifier);
ALTER RESOURCE GOVERNOR RECONFIGURE;

Same load as on Azure, 100 sessions calling a 30-second endpoint:

ErrorNumber  Sessions
0            100

Finished after (s)   Sessions
30                   22
60                   22
90                   22
120                  22
150                  12

The limit is applied to the unit: never more than 22 calls reach the endpoint. But there is no error. Every session ends up being served, and the last ones wait two minutes for it.

Where Resource Governor stops

During the second wave of that test, the group, the waits and the workers looked like this:

The 56 queued sessions wait on RESMGR_THROTTLED, and each of them has a worker. The instance counts 123 active workers against 45 at rest: 78 more, exactly the 22 calls in flight plus the 56 sessions in the queue.

Beyond the 22nd callAzure SQL DatabaseSQL Server 2025 with Resource GovernorWhat the session getserror 10928, immediatelya place in a queueWorker of that sessionreleasedheld until its turn comes and the call returnsCalls reaching the endpoint2222Worker poolprotectednot protected

Resource Governor protects the service being called. It does not protect the instance. With 600 sessions classified in that group, 22 calls would be in flight and the 578 others would still be queued, each holding a worker, against a pool of 512. I did not run that last case; it follows from the two measurements above.

What to take from this

On SQL Server 2025, every session waiting for an external endpoint holds a worker thread, and the engine sets no limit on how many can wait at once. Azure SQL Database does have such a cap, at 15% of its workers in my tests rather than the documented 10%, and a call beyond it is refused immediately. On-premises, a slow AI service plus a concurrent application is enough to exhaust the worker pool and to keep new connections out, with no blocking chain to look for and an error message, when there is one, that points at the endpoint.

The difference is also one of scope. In Azure SQL Database, the limit belongs to the database: a flood of slow calls is refused at the door of that database, and the 128 workers left keep it running. In SQL Server, the worker pool belongs to the instance. Every database on it shares the same 512 workers, so one application calling a slow AI service can lock out the users of all the others.

Resource Governor can cap the number of calls sent to the service, in Standard Edition too, but it queues the surplus instead of refusing it, and a queued session costs a worker. If you want the Azure behavior, the refusal has to come from the code that makes the call, or from the application in front of it. Make sure you can reach the dedicated admin connection before you need it: it works locally out of the box (sqlcmd -A), but from another machine it requires the remote admin connections option. It was the only way in during the saturation, and KILL on the waiting sessions frees their workers at once.

L’article Calling AI from SQL Server 2025 can lock everyone out of your on-prem instance est apparu en premier sur dbi Blog.

Removing instantiation filtering from a GoldenGate replicat

Yann Neuhaus - Mon, 2026-10-12 01:59

In a recent blog, I explained how instantiation filtering works. DBOPTIONS ENABLE_INSTANTIATION_FILTERING makes a replicat discard any record whose commit CSN is at or below a table’s instantiation CSN. It applies everything above it. This replicat parameter should be kept during the whole initial load process.

At some point the replicat has processed past the instantiation boundary for every table, and the filter has nothing left to do. Let’s answer the subsequent and very practical question: how to confirm, before editing the parameter file, that the replicat has cleared the boundary for every table it maps?

Which SCN should I check ?

To summarize what needs to be checked: it is safe to remove DBOPTIONS ENABLE_INSTANTIATION_FILTERING once the replicat last applied CSN is greater than the instantiation CSN of every table it maps.

To answer this question, you have two sources of information:

  • The per-table boundary, stored in dba_apply_instantiated_objects, with one row per source object.
  • The replicat last applied CSN, stored in the checkpoint table in the log_csn column.
SQL check

Read the boundaries first:

SELECT source_database, source_object_owner, source_object_name, instantiation_scn
FROM dba_apply_instantiated_objects
ORDER BY instantiation_scn DESC;
SOURCE_DATABASE  SOURCE_OBJECT_OWNER  SOURCE_OBJECT_NAME  INSTANTIATION_SCN
---------------- -------------------- ------------------- -----------------
PDB1             APP_PDB1             SALES               52642820
PDB1             APP_PDB1             ORDERS              52642649

Then read the replicat last applied CSN from its checkpoint table:

SELECT group_name, log_csn
FROM oggadmin.checkpoint
WHERE group_name = 'REP1';

You can safely remove ENABLE_INSTANTIATION_FILTERING when log_csn is greater than the highest instantiation_scn among the tables it maps. A one-shot verdict, scoped to a single source database:

SELECT 'REP1' AS group_name,
c.log_csn,
MAX(o.instantiation_scn) AS max_boundary,
CASE WHEN c.log_csn > MAX(o.instantiation_scn) THEN 'SAFE TO REMOVE' ELSE 'NOT YET' END AS verdict
FROM dba_apply_instantiated_objects o
LEFT JOIN oggadmin.checkpoint c ON c.group_name = 'REP1'
WHERE o.source_database = 'PDB1'
GROUP BY c.log_csn;

Before a replicat starts for the first time, log_csn is NULL and the verdict is NOT YET:

GROUP_NAME  LOG_CSN  MAX_BOUNDARY  VERDICT
----------- -------- ------------- -------
REP1                 52642820      NOT YET

A replicat may map more than one source database, or only a subset of the instantiated objects. Then narrow the join to the objects applied.

WARNING: A replicat that has never started has no checkpoint row at all, so log_csn returns nothing. Treat that as “not safe”: there is no applied position, so it cannot have cleared anything. The verdict query above handles this case. It starts from the instantiated objects and left joins the checkpoint table. A missing row gives a NULL log_csn, and the verdict falls to NOT YET instead of the query returning no row at all.

After some time, once the replicat catches up with the initial load, the same query returns:

GROUP_NAME  LOG_CSN   MAX_BOUNDARY  VERDICT
----------- --------- ------------- --------------
REP1        52643651  52642820      SAFE TO REMOVE

You can now cleanly delete the DBOPTIONS ENABLE_INSTANTIATION_FILTERING parameter and restart your replicat.

adminclient check

From the adminclient, INFO REPLICAT REP1, DETAIL reports the applied CSN without using sqlplus:

OGG> INFO REPLICAT REP1, DETAIL
...
Last Committed Transaction CSN value: 52643651

Compare that number against the instantiation_scn from the view exactly as above.

REST API check

The CSN is reachable over the REST API, just not from a GET endpoint. You need to execute a command against the replicat using the POST /services/{version}/replicats/{replicat}/command endpoint. Using execute_command_replicat in the oggrestapi Python client:

from oggrestapi import OGGRestAPI

client = OGGRestAPI(url="http://localhost:7810", username="ogg", password="ogg")

resp = client.execute_command_replicat("REP1", data={"command": "INFO", "arguments": "DETAIL"})
output = "".join(r["reply"])
print(output)
Replicat   REP1      Last Started 2026-09-20 13:29   Status RUNNING
Checkpoint Lag       00:00:00 (updated 00:00:02 ago)
Process ID           102660
Log Read Checkpoint  File aa000000002
                     2026-09-20 13:30:17.000000  RBA 18926
Encryption Profile   LocalWallet

Current Log BSN value: 52643543

Last Committed Transaction CSN value: 52646310

  Extract Source                          Begin             End

  aa000000002                             2020-01-01 00:00  2026-09-20 13:30:17.00
  aa000000000                             * Initialized *   2020-01-01 00:00:00.00
  aa000000000                             * Initialized *   First Record

To be truly automated, Last Committed Transaction CSN value has to be parsed out:

import re

match = re.search(r"Last Committed Transaction CSN value: (\d+)", output)
applied_csn = int(match.group(1))
print(applied_csn)
52646310
Information in the report file

When starting a replicat during an initial load, the report file is filled with the following lines:

OGG-10155  Instantiation CSN filtering is enabled on table PDB1.APP_PDB1.ORDERS at CSN 52,642,649.
OGG-10185  Instantiation CSN filtering on table PDB1.APP_PDB1.ORDERS has started at CSN 52642649.
OGG-10186  Instantiation CSN filtering on table PDB1.APP_PDB1.ORDERS has ended, now passing transactions starting at CSN 52642649.
  • If the trail the replicat reads on that start contains records below a boundary, it filters them, and these lines appear.
  • If the trail begins at or after the boundary, nothing is filtered and no line appears at all.
Performance impact of leaving ENABLE_INSTANTIATION_FILTERING

When migrating a database online with GoldenGate, you want your replicat to catch up quickly. I tested whether keeping ENABLE_INSTANTIATION_FILTERING in the parameter file had any effect on the lag of a replicat. I found no significant statistical evidence of this.

Summary
  • ENABLE_INSTANTIATION_FILTERING is safe to remove when the replicat log_csn (last applied CSN) is above the instantiation_scn of every table it maps.
  • Get the applied CSN from oggadmin.checkpoint.log_csn (sqlplus), INFO REPLICAT REP1, DETAIL (adminclient), or execute_command_replicat("REP1", data={"command": "INFO", "arguments": "DETAIL"}) over REST, which returns the same information.
  • The OGG-10155/10185/10186 report lines appear only when the replicat filters records on that start.

L’article Removing instantiation filtering from a GoldenGate replicat est apparu en premier sur dbi Blog.

Database Space Usage

Tom Kyte - Sun, 2026-10-11 23:04
We are in the process of purging/deleting data from some large tables ex. Our F42199 table had 63 million rows from which we deleted 10 million rows. Since deleting the 10 million rows we have inserted 4 millions new rows Prior to purging the 10 million rows the size of the F42199 table was 158GB derived by querying the dba_extents view. Today the table has grown to 260 GB, much to our surprise as we thought the empty blocks from the deleted rows would be reused. So the question is why are the empty blocks not being reused or why is the table size increasing?
Categories: DBA Blogs

Oracle Spatial Studio

Tom Kyte - Sun, 2026-10-11 23:04
Can an end user create spatial data in Oracle Spatial Studio by digitizing as line or polygon on an apex created front- end map screen and if so, can the user digitized feature be stored as sdo geometry in the Oracle database? For example, a technician entering a road project text data would be able to digitize the road within the Oracle cloud infrastructure using oracle spatial studio like you can with qgis and postgresql.
Categories: DBA Blogs

Striim 5.4.2 on macOS: Using Oracle Instant Client 26ai Drivers

DBASolved - Sun, 2026-10-11 16:08

Running Striim 5.4.2 on macOS against Oracle 26ai? Swap the bundled 21 drivers for Instant Client jars and set NATIVE_LIBS.

The post Striim 5.4.2 on macOS: Using Oracle Instant Client 26ai Drivers appeared first on DBASolved.

Categories: DBA Blogs

Will Oracle AI Database be renamed again to Oracle SI Database?

Tom Kyte - Fri, 2026-10-09 21:03
(Not so serious) question is in the subject :-)
Categories: DBA Blogs

how to find lock blockers and lock waiters in RAC

Tom Kyte - Fri, 2026-10-09 21:03
Hello, I know that in single instance I can use DBA_BLOCKERS and DBA_WAITERS to find blocking sessions and waiting sessions. But this does not work in RAC if blocking and waiting sessions run on different instances. How should I write the query using GV$LOCK in RAC ? Could you also explain what does GV$LOCK.BLOCK = 2 really mean and how this can be used; 2 - The lock is not blocking any blocked processes on the local node, but it may or may not be blocking processes on remote nodes. This value is used only in Oracle Real Application Clusters (Oracle RAC) configurations (not in single instance configurations). Thanks.
Categories: DBA Blogs

DBMS_DST.get_latest_timezone_version

Tom Kyte - Fri, 2026-10-09 21:03
Hi, just learned about DBMS_DST.get_latest_timezone_version today ( https://oracle-base.com/articles/misc/update-database-time-zone-file ) <code> SQL> SELECT * FROM v$timezone_file; FILENAME VERSION CON_ID -------------------- ---------- ---------- timezlrg_40.dat 40 0 SQL> SELECT DBMS_DST.get_latest_timezone_version from dual; GET_LATEST_TIMEZONE_VERSION --------------------------- 44 SQL> select banner_full from v$version; BANNER_FULL ---------------------------------------------------------------------------------------------------- Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production Version 19.28.0.0.0 </code>, want to know more about it (what does it do ? how does it work ?, what are prerequisities>?, which exceptions can it raise ?) however, it does not seem to be documented. ( neither https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_DST.html nor on https://docs.oracle.com/en/database/oracle/oracle-database/26/arpls/DBMS_DST.html )
Categories: DBA Blogs

How can I set JOB_CREATOR to the job owner when creating a Scheduler job in another schema?

Tom Kyte - Fri, 2026-10-09 21:03
Hi, I have a requirement where multiple users need to create Oracle Scheduler jobs in a dedicated target schema. For example, suppose I have two users: USER1 ? the user who creates the job USER2 ? the target schema and intended owner of the job If USER1 creates a Scheduler job for USER2, for example: BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'USER2.MY_JOB', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN NULL; END;', enabled => TRUE ); END; / the resulting job has: OWNER = USER2 JOB_CREATOR = USER1 This is expected behavior. However, there is an issue with this approach in our environment. If USER1 is later dropped from the database, the job still exists and its JOB_CREATOR points to a user that no longer exists. Our requirement is that when USER1 creates a job for USER2, both of the following should be USER2: OWNER = USER2 JOB_CREATOR = USER2 We tried creating a procedure in USER2 that calls DBMS_SCHEDULER.CREATE_JOB, and then calling that procedure from USER1. However, JOB_CREATOR is still recorded as USER1. Is there a supported way in Oracle to create a Scheduler job from USER1 for USER2 while having JOB_CREATOR recorded as USER2? Alternatively, is there a recommended Oracle architecture for this use case, especially when USER1 may be dropped later but the Scheduler jobs must remain valid and associated with USER2? Would Proxy Authentication, definer-rights procedures, or another mechanism be appropriate for this? Thank you.
Categories: DBA Blogs

Application Root uninstall issues

Tom Kyte - Fri, 2026-10-09 21:03
I have an application root with several applications ( from testing out the functionality) Example: Application A create user XXX Application B create table XXX.T1 ... Now I decide to uninstall application A <code>alter pluggable database application A begin uninstall;</code> but can't drop the user XXX <code>drop user XXX cascade;</code> Error report - ORA-00604: error occurred at recursive SQL level 1 ORA-65311: cannot modify the common object of another application so I realise I need to first drop the table XXX.T1 which was installed by application B, so I need to uninstall application B to do this but I can't end the uninstall of application A <code>alter pluggable database application A end uninstall;</code> Error report - ORA-65344: cannot uninstall or purge an application that has objects, users, roles, and profiles and I can't begin the uninstall of application B <code>ALTER PLUGGABLE DATABASE APPLICATION B BEGIN UNINSTALL;</code> Error report - ORA-65213: existing application action in progress If I try to drop the user outside of the application action <code>drop user XXX cascade</code> Error report - ORA-00604: error occurred at recursive SQL level 1 ORA-65311: cannot modify the common object of another application I'm stuck. When I check the objects in Application A there is none ( from dba_objects ) because the only thing in application A is the create user statement ( seen from dba_app_statements). How can I abort the uninstall of application A as this is preventing me from beginning an uninstall of application B ? Ideally I'd like to remove all the applications I created while testing this functionality. Thanks
Categories: DBA Blogs

Reg career path

Tom Kyte - Fri, 2026-10-09 21:03
HI Tom, My question is I have 9+ years of experience working in oracle as a developer with sql,pl/sql, forms,reports and Apex.. Do you think considering my experience it is required for me to go for developer with DBA or stay as Developer itself understanding the latest features in every new version of sql and pl/sql? Is it practically possible for me to be a developer and a DBA. Which is better for career opportunities and long stand in the industry. Your sincere suggestion on this is of great help fro my future career also. Thanks Prashanth R
Categories: DBA Blogs

Calling Oracle Apex from Oracle Forms without User ID and Password Authentication

Tom Kyte - Fri, 2026-10-09 21:03
We have an application developed using Oracle Forms and Oracle Reports, where application user IDs and passwords are maintained and authenticated within our database. As part of ongoing business requirements, we frequently receive requests for data extraction and reporting. We are currently evaluating Oracle APEX as a platform for developing these reports. We would appreciate your guidance on the following questions: 1. Can reports developed in Oracle APEX be launched directly from Oracle Forms? a) If this is supported, what is the recommended integration approach? 2.What is the launch mechanism for invoking an Oracle APEX report from Oracle Forms? Could you provide a sample URL or reference architecture demonstrating this integration? 3.How should user authentication be handled between Oracle Forms and Oracle APEX? a) Is a separate login to Oracle APEX required when a user launches an APEX report from Oracle Forms? b) Alternatively, can Oracle APEX leverage the existing authenticated user session from Oracle Forms, enabling a seamless Single Sign-On (SSO) experience without prompting the user to log in again?
Categories: DBA Blogs

Moving data from one partition to another partition of the same table -Best methods

Tom Kyte - Fri, 2026-10-09 21:03
1. The table is partitioned by list ex: week1_user1, week2_user1 2. Each partition contains around 900M records 3. Every week, we are truncating the week2_user1 partition and moving the data from week1_user1 to week2_user1 <code>insert /*+ parallel(8) enable_parallel_dml */ into t1 select /*+ FULL(t1) */'week2_user1' col1,col2,col3 from t1 where col1='week1_user1';</code> col1 is the partition by list column 4. Plan looks like <code> -------------------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | INSERT STATEMENT | | | | 78705 (100)| | | | | | | | 1 | PX COORDINATOR | | | | | | | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10002 | 682M| 165G| 78705 (15)| 00:00:07 | | | Q1,02 | P->S | QC (RAND) | | 3 | INDEX MAINTENANCE | T1 | | | | | | | Q1,02 | PCWP | | | 4 | PX RECEIVE | | 682M| 165G| 78705 (15)| 00:00:07 | | | Q1,02 | PCWP | | | 5 | PX SEND RANGE | :TQ10001 | 682M| 165G| 78705 (15)| 00:00:07 | | | Q1,01 | P->P | RANGE | | 6 | LOAD AS SELECT (HIGH WATER MARK BROKERED)| T1| | | | | | | Q1,01 | PCWP | | | 7 | OPTIMIZER STATISTICS GATHERING | | 682M| 165G| 78705 (15)| 00:00:07 | | | Q1,01 | PCWP | | | 8 | PX RECEIVE | | 682M| 165G| 78705 (15)| 00:00:07 | | | Q1,01 | PCWP | | | 9 | PX SEND RANDOM LOCAL | :TQ10000 | 682M| 165G| 78705 (15)| 00:00:07 | | | Q1,00 | P->P | RANDOM LOCA| | 10 | PX BLOCK ITERATOR | | 682M| 165G| 78705 (15)| 00:00:07 | KEY | KEY | Q1,00 | PCWC | | |* 11 | TABLE ACCESS FULL | T1| 682M| 165G| 78705 (15)| 00:00:07 | KEY | KEY | Q1,00 | PCWP | | ------------------------------------------------------------------------------------------------------------------------------------------------------------...
Categories: DBA Blogs

Oracle Forensics - Can we Understand what Happened?

Pete Finnigan - Fri, 2026-10-09 21:03
In forensics the evidence can be grouped into two blocks. The first is changes made to the database and the second is read activity. Usually an attackers goal is to steal data (read) but he may need to do changes....[Read More]

Posted by Pete On 06/10/26 At 02:16 PM

Categories: Security Blogs

Generate a PL/SQL Encryption and Decryption Package, Again

Pete Finnigan - Fri, 2026-10-09 21:03
First, I am appending this text here before I post this blog live as I realised its almost exactly 22 years since I started this blog in September 2004; so happy birthday to my blog!! Now to the actual subject....[Read More]

Posted by Pete On 28/09/26 At 08:36 AM

Categories: Security Blogs

Extreme PL/SQL - Creating a simple programming language interpreter in PL/SQL

Pete Finnigan - Fri, 2026-10-09 21:03
Last week I posted a blog - Extreme PL/SQL - Running an Assembly Language Program in PL/SQL where I presented the fact that I have written a virtual machine on PL/SQL and also an assembler in PL/SQL and showed how....[Read More]

Posted by Pete On 23/09/26 At 07:52 AM

Categories: Security Blogs

Extreme PL/SQL - Running an Assembly Language Program in PL/SQL

Pete Finnigan - Fri, 2026-10-09 21:03
Back in 2022 I started work on an idea that I could build an interpreter for a simple language in PL/SQL and then building on that create a Virtual Machine in PL/SQL and an assembler in PL/SQL for the assembly....[Read More]

Posted by Pete On 16/09/26 At 08:54 AM

Categories: Security Blogs

Oracle Security AnythingLLM Tools

Pete Finnigan - Fri, 2026-10-09 21:03
As you will have noticed in my blogs I have been using and playing with AI and Large Language Models (LLMs) for a while now but with a focus on Oracle Security still. I want to understand the capabilities of....[Read More]

Posted by Pete On 10/09/26 At 10:35 AM

Categories: Security Blogs

Perform a Security Audit of an Old Oracle Database

Pete Finnigan - Fri, 2026-10-09 21:03
We support doing security audits of all of the current Oracle databases from 19c to 21c and 26ai. We also support doing security audits on databases in your own data center or in the cloud. No matter where the database....[Read More]

Posted by Pete On 09/09/26 At 12:33 PM

Categories: Security Blogs

Can Synonyms Point to Synonyms?

Pete Finnigan - Fri, 2026-10-09 21:03
I got asked a question via a DM on one of my social media channels a few days ago and thought it worth an investigation. They asked me; Can an Oracle synonym point to another synonym, ad infinitum. Let me....[Read More]

Posted by Pete On 07/09/26 At 08:08 AM

Categories: Security Blogs

Pages

Subscribe to Oracle FAQ aggregator