O2SS0343: l'istruzione FORALL con clausola SAVE EXCEPTION non è supportata (Errore)
Questo articolo descrive perché SQL Server Migration Assistant (SSMA) per Oracle non supporta la SAVE EXCEPTIONS
clausola nell'istruzione FORALL
.
Background
La gestione delle eccezioni è un costrutto o un meccanismo del linguaggio di programmazione progettato per gestire l'occorrenza di eccezioni, condizioni speciali che modificano il normale flusso di esecuzione del programma. In Oracle l'istruzione FORALL
consente di eseguire più istruzioni DML in modo molto efficiente e può ripetere solo una singola istruzione DML, a differenza di un FOR
ciclo generico. SAVE EXCEPTIONS
la clausola fa sì che il FORALL
ciclo continui anche se alcune operazioni DML hanno esito negativo.
Il modello di eccezione Oracle differisce da SQL Server sia nella generazione di eccezioni che nella gestione delle eccezioni. È preferibile usare il modello di eccezioni di SQL Server come parte della migrazione del codice ORACLE PL/SQL.
Ogni volta che FORALL
l'istruzione usata con SAVE EXCEPTIONS
la clausola , SSMA non la supporta e genera un messaggio di errore.
Esempio
Si consideri l'esempio seguente che usa un'istruzione FORALL
con SAVE EXCEPTIONS
clausola .
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;
Quando si tenta di convertire il codice precedente in SSMA, viene generato il messaggio di errore seguente:
O2SS0343: l'istruzione FORALL con clausola SAVE EXCEPTIONS non è supportata
Possibili rimedi
Una possibile correzione consiste nell'usare il blocco try e catch per gestire le eccezioni in T-SQL usando ERROR_NUMBER
funzioni e anziché le SQLCODE
funzioni Oracle e SQLERRM
ERROR_MESSAGE
. Per questo motivo, è necessario aggiornare il codice di SQL Server come indicato di seguito:
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
Messaggi di conversione correlati
- O2SS0282: RAISE senza eccezione specificata può essere inserito solo nel gestore eccezioni
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per