Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article explique pourquoi Assistant Migration SQL Server (SSMA) pour Oracle ne prend pas en charge la SAVE EXCEPTIONS
clause dans l’instructionFORALL
.
Background
La gestion des exceptions est une construction ou un mécanisme de langage de programmation conçu pour gérer l’occurrence d’exceptions, des conditions spéciales qui modifient le flux normal d’exécution du programme. Dans Oracle, FORALL
l’instruction vous permet d’exécuter efficacement plusieurs instructions DML et ne peut répéter qu’une seule instruction DML, contrairement à une boucle à usage FOR
général. SAVE EXCEPTIONS
la clause provoque la poursuite de la FORALL
boucle même si certaines opérations DML échouent.
Le modèle d’exception Oracle diffère de SQL Server à la fois dans le déclenchement d’exceptions et la gestion des exceptions. Il est préférable d’utiliser le modèle d’exceptions SQL Server dans le cadre de la migration de code Oracle PL/SQL.
Chaque fois que FORALL
l’instruction utilisée avec SAVE EXCEPTIONS
la clause, SSMA ne la prend pas en charge et génère un message d’erreur.
Exemple
Dans l’exemple suivant, vous utilisez une FORALL
instruction avec SAVE EXCEPTIONS
une clause.
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;
Lorsque vous essayez de convertir le code précédent dans SSMA, il génère le message d’erreur suivant :
O2SS0343 : l’instruction FORALL avec la clause SAVE EXCEPTIONS n’est pas prise en charge
Solutions possibles
Une correction possible consiste à utiliser le bloc try and catch pour gérer les exceptions dans T-SQL à l’aide ERROR_NUMBER
SQLCODE
et ERROR_MESSAGE
aux fonctions au lieu des fonctions Oracle.SQLERRM
Mettez à jour le code SQL Server comme suit :
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
Messages de conversion connexes
- O2SS0282 : RAISE sans exception spécifiée ne peut être placé que dans le gestionnaire d’exceptions