Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article covers some of the reasons why SQL Server Migration Assistant (SSMA) for Oracle doesn't convert the PL/SQL blocks containing PRAGMA AUTONOMOUS_TRANSACTION
statement on the block level (that is, standalone BEGIN ... END
).
Background
Autonomous Transactions allow you to create a new sub-transaction that might commit or roll back changes independent of the parent transaction. PRAGMA
refers to a compiler directive, and is used to provide an instruction to the compiler.
In Oracle, when you define a PL/SQL block as an Autonomous Transaction, it isolates the DML in that block from the caller's transaction context. The block becomes an independent transaction started by another transaction, referred to as the main transaction. To mark a PL/SQL block as an autonomous transaction, include the following statement in your declaration section:
PRAGMA AUTONOMOUS_TRANSACTION;
In the previous statement, PRAGMA
can perform an autonomous transaction within a PL/SQL block between a BEGIN
and END
statement without affecting the entire transaction.
Whenever SSMA tries to convert the PL/SQL block with PRAGMA AUTONOMUS_TRANSACTION
statement (that is, standalone BEGIN ... END
), it doesn't support PRAGMA
on the block level. This is because SSMA can't find its corresponding object in SQL Server. But SSMA can convert autonomous transactions at the routine level (that is, for procedures, functions etc.).
Example
Consider the following example:
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
FOR i IN 3 .. 10 LOOP
INSERT INTO at_test (id, description)
VALUES (i, 'Description for ' || i);
END LOOP;
COMMIT;
END;
When SSMA tries to convert the previous PL/SQL block, it gives following error:
O2SS0205: Unable to convert PRAGMA AUTONOMUS_TRANSACTION
Possible remedies
To convert a PL/SQL block with an AUTONOMOUS_TRANSACTION
statement, you should wrap the code into a procedure, function, or trigger. In the previous example, you can define a procedure to insert the data into the at_test
table as an autonomous transaction. The solution to the previous issue is as follows:
CREATE OR REPLACE PROCEDURE Insert_Data
AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
FOR i IN 3 .. 10 LOOP
INSERT INTO at_test (id, description)
VALUES (i, 'Description for ' || i);
END LOOP;
COMMIT;
END;
How SSMA converts an autonomous transaction
To convert the previous Autonomous Transaction statement, SSMA uses the extended stored procedure emulator xp_ora2ms_exec2_ex
. After SSMA creates the autonomous block as separate procedure, it calls this procedure using the xp_ora2ms_exec2_ex
emulator as shown in the following example.
BEGIN
DECLARE
@active_spid INT,
@login_time DATETIME
SET @active_spid = ssma_oracle.get_active_spid()
SET @login_time = ssma_oracle.get_active_login_time()
EXECUTE master.dbo.xp_ora2ms_exec2_ex
@active_spid,
@login_time,
DB_NAME(),
N'DBO',
N'INSERT_DATA$IMPL',
N'false'
END
Internally xp_ora2ms_exec2_ex
connects back to the same instance of SQL Server using current credentials and executes the given stored procedure (INSERT_DATA$IMPL
in the previous sample). Since it's a separate connection, modifications done by the executed stored procedure can be committed or rolled back separately from the calling transaction.
Since new connection has to be opened to SQL Server, such conversion is relatively slow, compared to native Oracle implementations. Whenever possible, rewrite the code without the Autonomous Transaction.
Related conversion messages
- O2SS0292: PRAGMA AUTONOMUS_TRANSACTION converted
- O2SS0308: PRAGMA AUTONOMOUS_TRANSACTION ignored