非循環データによる永久再帰処理を回避 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLデータ定義言語 詳細トピック

Product
Advanced SQL Engine
Teradata Database
Release Number
17.05
17.00
Published
2020年6月
ft:locale
ja-JP
ft:lastEdition
2021-03-30
dita:mapPath
ja-JP/jpx1556733107962.ditamap
dita:ditavalPath
ja-JP/jpx1556733107962.ditaval
dita:id
B035-1184
Product Category
Software
Teradata Vantage

永久再帰処理の問題は循環データだけではありません。クエリー データが循環しない場合でも、意味的に不正なクエリーによって永久に再帰する場合があります。永久ループの原因となる意味的に不正な結合条件は独特の問題です。そのような条件の部分的なリストには次のものが含まれます。

  • 不正な列を結合する。
  • 結合から不正な列を選択する。
  • 複数の結合条件で、AND演算子の代わりにOR演算子を使用する。
  • 結合テーブルに相関名を付けた後で、間違って結合テーブルの元の名前を参照する。

    この場合、システムはクエリーを2つのテーブルの結合ではなく、3つのテーブルの結合を指定するものと解釈します。その結果、「3つ目」のテーブルには結合条件がないため、相互結合が作成されます。

  • 結合条件を重複指定する。

次の例は、述部rec.depth <= 1000によってのみ限定される重複したケースを図示しています。このトートロジーは、シード クエリーのWHERE条件がcol_1の値が2である1行だけを返すのに対し、再帰的クエリーのWHERE条件がcol_1の値が2または3のどちらかである行のみを返すことによって生じます。再帰処理のたびにcol_1の値が2である行が生成されるので、条件WHERE rec.depth =1000がなければ無限ループになるところです。

次のデータを持つテーブルTがあるとします。

T
Col_1 Col_2
2 3
4 5
6 7
8 9

次に、以下の再帰的ビューを作成します。

    CREATE RECURSIVE VIEW rec (a, depth) AS (
      SELECT col_1, 0 AS depth
      FROM t
      WHERE col_1 = 2
    UNION ALL
      SELECT a, rec.depth + 1
      FROM t, rec
      WHERE t.col_1 IN (2, 3)
      AND   rec.depth <= 1000);

このビューに対する次のクエリーは、その値がすべて2である1,001個の行を持つ結果セットを生成します。再帰処理はクエリーがその限界値に達した場合にのみ停止します。限界が設定されない場合、ディスク領域のスプールが使い果たされるまでクエリーは続きます。

    SELECT a
    FROM rec;

クエリーの結果セットは次のようになります。省略記号は994の追加行を示し、その値はそれぞれ2です。

A
2
2
2
2
2
2

同じ問題が、同じテーブルtに基づく次の再帰的ビュー定義でも生じます。この再帰的ビューも重複した検索条件によって定義されますが、前の例で指定したIN句の代わりにEXISTS句を指定します。

    CREATE RECURSIVE VIEW rec (a, depth) AS (
      SELECT col_1, 0 AS depth
      FROM t
      WHERE col_1 = 2
      AND   EXISTS
             (SELECT col_1
              FROM t)
    UNION ALL
      SELECT a, rec.depth + 1
      FROM t, rec
      WHERE rec.a = t.col_1
      AND   rec.depth <= 1000);

この再帰的ビューに対する次のクエリーは、IN句の例と同じ結果セットを生成します。 1,001行はすべて値2を持ちます。

    SELECT a
    FROM rec;