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 describen los motivos por los que SQL Server Migration Assistant (SSMA) para Oracle no admite la comparación de variables de registro o recopilación.
Fondo
Una colección es un grupo ordenado de elementos, todo el mismo tipo. Es un concepto general que abarca listas, matrices y otros tipos de datos conocidos. Cada elemento tiene un subíndice único que determina su posición en la colección.
Cada vez que se encuentra un bloque PL/SQL con operador de comparación como =
o IN
con operandos de colección o registro de tipos, SSMA genera un mensaje de error.
Ejemplo
En el ejemplo siguiente, se comparan dos colecciones mediante el =
operador :
DECLARE
TYPE SIMPLE_COLLECTION IS TABLE OF INTEGER;
VARCOLL1 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 1, 1);
VARCOLL2 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 1, 1);
BEGIN
IF VARCOLL1 = VARCOLL2 THEN
DBMS_OUTPUT.PUT_LINE(1);
ELSE
DBMS_OUTPUT.PUT_LINE(0);
END IF;
END;
Al intentar convertir el código anterior en SSMA, genera el siguiente mensaje de error:
O2SS0347: no se admite la comparación de expresiones de registro o colección
Posibles soluciones
La solución al error anterior es volver a escribir el código en Oracle. A diferencia de Oracle, SQL Server no admite registros o colecciones y sus operaciones asociadas. Por lo tanto, al migrar de Oracle a SQL Server mediante SSMA, debe aplicar transformaciones sustanciales al código PL/SQL.
Este es el código de Oracle reescrito:
DECLARE
TYPE SIMPLE_COLLECTION IS TABLE OF INTEGER;
VARCOLL1 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 2,3);
VARCOLL2 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 2,3);
j PLS_INTEGER := 0;
BEGIN
IF VARCOLL1.count=VARCOLL2.count THEN
FOR i IN 1..VARCOLL1.count
LOOP
IF VARCOLL1(i) = VARCOLL2(i) THEN
j:=1;
ELSE
j:=0;
DBMS_OUTPUT.PUT_LINE(0);
EXIT;
END IF;
END LOOP;
IF j = 1 THEN
DBMS_OUTPUT.PUT_LINE(1);
END IF;
ELSE
DBMS_OUTPUT.PUT_LINE(0);
END IF;
END;
Esto se traduce al siguiente código de Transact-SQL mediante SSMA:
BEGIN
DECLARE
@CollectionIndexInt$TYPE varchar(max) = ' TABLE OF INT'
DECLARE
@VARCOLL1 dbo.CollectionIndexInt =
dbo.CollectionIndexInt::[Null]
.SetType(@CollectionIndexInt$TYPE)
.AddInt(1)
.AddInt(2)
.AddInt(3),
@VARCOLL2 dbo.CollectionIndexInt =
dbo.CollectionIndexInt::[Null]
.SetType(@CollectionIndexInt$TYPE)
.AddInt(1)
.AddInt(2)
.AddInt(3),
@j int = 0
IF @VARCOLL1.Count = @VARCOLL2.Count
BEGIN
BEGIN
DECLARE
@i int
SET @i = 1
DECLARE
@loop$bound int
SET @loop$bound = @VARCOLL1.Count
WHILE @i <= @loop$bound
BEGIN
IF @VARCOLL1.GetInt(@i) = @VARCOLL2.GetInt(@i)
SET @j = 1
ELSE
BEGIN
SET @j = 0
PRINT 0
BREAK
END
SET @i = @i + 1
END
END
IF @j = 1
PRINT 1
END
ELSE
PRINT 0
END