Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se describe por qué SQL Server Migration Assistant (SSMA) para Oracle no admite la SAVE EXCEPTIONS
cláusula en la FORALL
instrucción .
Fondo
El control de excepciones es una construcción o mecanismo de lenguaje de programación diseñado para controlar la aparición de excepciones, condiciones especiales que cambian el flujo normal de ejecución del programa. En Oracle, la FORALL
instrucción le permite ejecutar varias instrucciones DML de forma eficaz y solo puede repetir una sola instrucción DML, a diferencia de un bucle de uso FOR
general. SAVE EXCEPTIONS
la cláusula hace que el FORALL
bucle continúe incluso si se produce un error en algunas operaciones DML.
El modelo de excepciones de Oracle difiere de SQL Server tanto en la generación de excepciones como en el control de excepciones. Es preferible usar el modelo de excepciones de SQL Server como parte de la migración de código PL/SQL de Oracle.
Cada vez que se FORALL
usa la instrucción con SAVE EXCEPTIONS
la cláusula , SSMA no la admite y genera un mensaje de error.
Ejemplo
En el ejemplo siguiente, se usa una FORALL
instrucción con SAVE EXCEPTIONS
cláusula .
CREATE TABLE DIVISION_RESULT_Exception (RESULT NUMBER);
/
DECLARE
TYPE NUMLIST IS TABLE OF NUMBER;
NUM_TAB NUMLIST := NUMLIST(1000, 0, 100, 0, 10);
ERRORS NUMBER;
DML_ERRORS EXCEPTION;
PRAGMA EXCEPTION_INIT(DML_ERRORS, -24381);
BEGIN
FORALL i IN NUM_TAB.FIRST..NUM_TAB.LAST
SAVE EXCEPTIONS
INSERT INTO DIVISION_RESULT_Exception
VALUES(1000 / NUM_TAB(i));
EXCEPTION
WHEN DML_ERRORS THEN
ERRORS := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.PUT_LINE('Number of errors is ' || ERRORS);
FOR i IN 1..ERRORS LOOP
DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' ||SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
Al intentar convertir el código anterior en SSMA, genera el siguiente mensaje de error:
O2SS0343: no se admite la instrucción FORALL con la cláusula SAVE EXCEPTIONS.
Posibles soluciones
Una posible corrección consiste en usar el bloque try y catch para controlar las excepciones en T-SQL mediante ERROR_NUMBER
funciones y ERROR_MESSAGE
en lugar de las SQLCODE
funciones de Oracle y SQLERRM
.
Actualice el código de SQL Server de la manera siguiente:
BEGIN
/* Declaration and initialization of table of input values */
DECLARE
@CollectionIndexInt$TYPE varchar(max) = ' TABLE OF DOUBLE'
DECLARE
@NUM_TAB dbo.CollectionIndexInt =
dbo.CollectionIndexInt::[Null]
.SetType(@CollectionIndexInt$TYPE)
.AddDouble(1000)
.AddDouble(0)
.AddDouble(100)
.AddDouble(0)
.AddDouble(10)
/* Declaration and initialization of other variables */
DECLARE
@ERRORS int,
@DML_ERRORS$exception nvarchar(1000)
SET @DML_ERRORS$exception = N'ORA-24381%'
/* Declaration and initialization of temporary variables */
DECLARE
@i int
SET @i = 1
/* Running the loop for all the input values*/
WHILE @i <= @NUM_TAB.Count
BEGIN
/* Performing the required operation in Try block */
BEGIN TRY
INSERT dbo.DIVISION_RESULT_EXCEPTION(RESULT)
VALUES (1000 / @NUM_TAB.GetDouble(@i))
END TRY
/* Catch block to handle exception generated in Try block */
BEGIN CATCH
SET @Errors = @Errors + 1;
PRINT ('SQL error is ' + CONVERT(varchar(20), ERROR_NUMBER()) +
':' + CONVERT(varchar(100), ERROR_MESSAGE()))
PRINT (CONVERT(Varchar(30), ERROR_NUMBER()))
END CATCH;
/* Incrementing the loop variable */
SET @i = @i + 1
END
END
Mensajes de conversión relacionados
- O2SS0282: RAISE sin excepción especificada solo se puede colocar en el controlador de excepciones.