Compartir a través de


O2SS0021: instrucción con ROWNUM no convertido (error)

En este artículo se describen algunos de los motivos por los que SQL Server Migration Assistant (SSMA) para Oracle no puede convertir una instrucción que contenga la pseudocolumna de Oracle ROWNUM .

Fondo

Oracle ROWNUM devuelve un número que indica el orden en el que se seleccionó una fila de una tabla. La primera fila seleccionada tiene un ROWNUM de 1; la segunda fila tiene un ROWNUM de 2, etc.

Cuando SSMA convierte la ROWNUM pseudocolumna, proporciona dos formas de emulación:

  1. Con la TOP palabra clave de la SELECT instrucción , si esta pseudocolumna solo se usa para limitar el tamaño del conjunto de resultados.
  2. Con la ROW_NUMBER() función , si los números de fila aparecen en una SELECT lista.

Hay dos casos en los que SSMA decide que no puede convertir la ROWNUM pseudocolumna en SQL Server y, por tanto, genera el O2SS0021 mensaje de error:

Escenario 1: ROWNUM se incluye como parte de una cláusula compleja WHERE .

Escenario 2: ROWNUM se usa en una WHERE cláusula como esta: WHERE ROWNUM > {positive integer}.

Posibles soluciones

Escenario 1: ROWNUM se incluye como parte de una cláusula compleja WHERE

Considere el ejemplo siguiente:

DELETE
    FROM employees
WHERE
    ROWNUM - 1 <= 11 + 1
    AND employeeid > 10;

La solución consiste en simplificar la expresión para que ROWNUM sea ROWNUM <= 11. El resultado final se traduciría para usar la TOP cláusula . A continuación se muestra una consulta simplificada:

DELETE
    FROM employees
WHERE
    ROWNUM <= 11
    AND employeeid > 10;

SSMA convierte esta consulta de la siguiente manera:

DELETE TOP(11)
    [dbo].[EMPLOYEES]
WHERE
    [EMPLOYEES].[EMPLOYEEID] > 10

En el ejemplo siguiente, SSMA no sabe cómo analizar ROWNUM con la IN cláusula :

DELETE
    FROM employees
WHERE
    ROWNUM in (1, 2, 3, 4);

En lugar de intentar traducir esta cláusula literalmente, considere la posibilidad de usar una WHERE cláusula que use la clave principal o un identificador único, especialmente cuando no haya ninguna ORDER BY cláusula. Por ejemplo, use la columna employeeid de clave principal en lugar de ROWNUM lo siguiente:

DELETE
    FROM employees
WHERE
    employeeid IN (1, 2, 3, 4);

Escenario 2: ROWNUM se usa en una WHERE cláusula como esta: WHERE ROWNUM > {positive integer}

Considere el ejemplo siguiente:

SELECT
    employeeid
FROM
    employees
WHERE
    ROWNUM > 2 OR employeeid > 8;

Siempre que se usa ROWNUM > {positive integer}, la expresión siempre se evalúa como false. SSMA notifica el problema mediante el error O2SS0021. Para resolver este problema, quite la ROWNUM > 2 expresión.

En la mayoría de estas situaciones, tenga en cuenta lo que intenta lograr la consulta y volver a escribirla para usar la ROW_NUMBER() emulación, TOP la cláusula o usar una expresión única para las WHEREcláusulas , GROUP BYo ORDER BY .