次の方法で共有


O2SS0021: ROWNUM が変換されていないステートメント (エラー)

この記事では、Oracle 用 SQL Server Migration Assistant (SSMA) が Oracle を含むステートメントを疑似列 ROWNUM 変換できない理由について説明します。

背景

Oracle ROWNUM は、テーブルから行が選択された順序を示す数値を返します。 選択した最初の行には1ROWNUMがあります。2 番目の行には2ROWNUMがあります。

SSMA は、 ROWNUM 擬似列を変換するときに、次の 2 つの形式のエミュレーションを提供します。

  1. この疑似列が結果セットのサイズを制限するためにのみ使用される場合は、SELECT ステートメントの TOP キーワードを使用します。
  2. ROW_NUMBER()関数では、行番号がSELECTリストに表示される場合。

SSMA が、 ROWNUM 擬似列を SQL Server に変換できないと判断し、そのため、 O2SS0021 エラー メッセージが生成される場合は 2 つあります。

シナリオ 1: ROWNUM は、複雑な WHERE 句の一部として含まれています。

シナリオ 2: ROWNUM は、次のような WHERE 句で使用されます: WHERE ROWNUM > {positive integer}

考えられる対処方法

シナリオ 1: 複雑なWHERE句の一部としてROWNUMが含まれる

次の例を確認してください。

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

解決策は、 ROWNUMROWNUM <= 11するための式を簡略化することです。 最終的な結果は、 TOP 句を使用するように変換されます。 簡略化されたクエリは次のとおりです。

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

SSMA は、このクエリを次のように変換します。

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

次の例では、SSMA は IN 句を使用してROWNUMを解析する方法を認識していません。

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

この句をリテラルで変換するのではなく、主キーまたは一意識別子を使用する WHERE 句を使用することを検討してください(特に、 ORDER BY 句がない場合)。 たとえば、次のようにROWNUMではなく、主キー列employeeidを使用します。

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

シナリオ 2: ROWNUM は、次のような WHERE 句で使用されます。 WHERE ROWNUM > {positive integer}

次の例を確認してください。

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

ROWNUM > {positive integer}を使用するたびに、式は常にfalseに評価されます。 SSMA は、エラー O2SS0021を使用して問題を報告します。 この問題を解決するには、 ROWNUM > 2 式を削除します。

このような状況のほとんどで、 ROW_NUMBER() エミュレーション、 TOP 句を使用したり、 WHEREGROUP BY、または ORDER BY 句に一意の式を使用したりするために、クエリが何を実行して書き直そうとしているのかを検討してください。