SnowConvert AI - Oracle COLLECTIONS AND RECORDS

Oracle COLLECTIONS および RECORDS を Snowflakeスクリプトに変換するための変換リファレンス

警告

このセクションは進行中であり、情報は将来変更される可能性があります。

概要

PL/SQL では、コレクションと記録の2種類の複合データ型を定義できます。複合とは、内部コンポーネントを持つ値を格納するデータ型のことです。

コレクションでは、内部コンポーネントは常に同じデータ型を持ち、要素と呼ばれます。

記録では、内部コンポーネントは異なるデータ型を持つことができ、フィールドと呼ばれます。(Oracle PL/SQL 言語リファレンス COLLECTIONS AND RECORDS)

注釈

一部の回避策は重複しており、両方のシナリオで機能する可能性があるため、[CREATE TYPE 文の変換リファレンス](../sql-translation-reference/create_type.md)を考慮してください。

制限事項

Snowflakeは、オンラインドキュメント サポートされていないデータ型 によると、 PL コレクションと記録を含むユーザー定義データ型をサポートしていませんが、 半構造化データ型 をサポートしており、これは記録の階層のような構造とコレクションユーザー定義型の要素構造の両方を模倣するために使用することができます。このため、回避策がない機能のタイプが複数あります。

以下は、 NO 回避策が提案されている機能です。

変数のサイズは 16MB を超えることはできません

Snowflakeは VARIANT、 OBJECT、 ARRAY の最大サイズを 16MBs にセットします。つまり、記録、コレクション、またはいずれかの要素がこのサイズを超えると、ランタイムエラーが発生します。

Varrayの容量を制限することはできません

OracleのVarraysは、その中の要素数を制限することができます。これはSnowflakeではサポートされていません。

提案されている回避策

記録タイプの定義について

提案されている回避策は、Oracleのデータ型を模倣するために「OBJECT」半構造化データ型を使用することです。

コレクションタイプの定義について

移行するコレクションのタイプによって、2つの異なる回避策があります。

  • 連想配列は、「OBJECT」半構造化データ型に変更されることが提案されています。

  • Varraysとネストされたテーブル配列は、「ARRAY」半構造化データ型に変更されることが提案されています。

現在の SnowConvert AI サポート

次の表は、 SnowConvert AI ツールで現在提供されているサポートの概要を示しています。変換がまだ最終的なものではない可能性があること、さらに作業が必要になる可能性があることにご注意ください。

サブ機能

現在の認識ステータス

現在の変換ステータス

既知の回避策がある

[レコードタイプ定義](#record-type-definition)

認識されています。

変換されていません。

あり。

[連想配列型の定義](#associative-array-type-definition)

認識されません。

変換されていません。

あり。

[Varray型の定義](#varray-type-definition)

認識されています。

変換されていません。

あり。

[ネストされたテーブルの配列型定義](#nested-table-array-type-definition)

認識されています。

変換されていません。

あり。

既知の問題

1.連想配列はネストされたテーブルとみなされます

現在、 SnowConvert AI は連想配列とネストされたテーブルを区別していないため、同じ評価カウントで混在しています。

連想配列型の定義

これは、Oracleの連想配列宣言をSnowflakeに変換するための変換リファレンスです

警告

このセクションは進行中であり、情報は将来変更される可能性があります。

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

連想配列(以前は PL/SQL テーブルまたはインデックスバイテーブルと呼ばれていました)はキー値のペアのセットです。各キーは一意なインデックスで、構文 variable_name(index) で関連する値を探すのに使われます。

インデックス のデータ型は、文字列型(VARCHAR2VARCHARSTRING、または LONG)または PLS_INTEGER のいずれかです。インデックスは作成順ではなく、ソート順で格納されます。文字列型の場合、ソート順は初期化パラメーター NLS_SORTNLS_COMP によって決定されます。

(Oracle PL/SQL 言語リファレンス ASSOCIATIVE ARRAYS)

警告

PL/SQL NESTED TABLE 型定義と混同しないでください。

翻訳のために、型定義は OBJECT 半構造化データ型 に置き換えられ、その使用はあらゆる操作にわたって適宜変更されます。

連想配列型を定義するための構文は以下の通りです。

type_definition := TYPE IS TABLE OF datatype INDEX BY indexing_datatype;

indexing_datatype := { PLS_INTEGER
                     | BINARY_INTEGER
                     | string_datatype
                     }
Copy

この型の変数を宣言するには

variable_name collection_type;

Copy

サンプルソースパターン

Varcharインデックス付き連想配列

Oracle
CREATE OR REPLACE PROCEDURE associative_array
IS
    TYPE associate_array_typ IS TABLE OF INTEGER
        INDEX BY VARCHAR2(50);
        
    associate_array associate_array_typ := associate_array_typ();
    associate_index VARCHAR2(50);
BEGIN
    associate_array('abc') := 1;
    associate_array('bca') := 2;
    associate_array('def') := 3;
    
    DBMS_OUTPUT.PUT_LINE(associate_array('abc'));
    associate_array('abc') := 4;
    --THROWS 'NO DATA FOUND'
    --DBMS_OUTPUT.PUT_LINE(associate_array('no exists'));
    
    DBMS_OUTPUT.PUT_LINE(associate_array.COUNT);
    
    associate_index := associate_array.FIRST;
    WHILE associate_index IS NOT NULL
    LOOP
        DBMS_OUTPUT.PUT_LINE(associate_array(associate_index));
        associate_index := associate_array.NEXT(associate_index);
    END LOOP;
END;

CALL associative_array();
Copy
結果

DBMS に OUTPUT

1

3

4

2

3

Snowflake

OBJECT_INSERT の「true」パラメーターに注意してください。これは、その要素がすでに配列内に存在する場合に、その要素が更新されるようにするためです。

CREATE OR REPLACE PROCEDURE PUBLIC.associative_array ()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
   DECLARE
      associate_array OBJECT := OBJECT_CONSTRUCT();
      associate_index VARCHAR(50);
   BEGIN
      associate_array := OBJECT_INSERT(associate_array, 'abc', 1, true);
      associate_array := OBJECT_INSERT(associate_array, 'bca', 2, true);
      associate_array := OBJECT_INSERT(associate_array, 'def', 3, true);

      CALL DBMS_OUTPUT.PUT_LINE(:associate_array['abc']);
      CALL DBMS_OUTPUT.PUT_LINE(:associate_array['not found']);
      
      associate_array := OBJECT_INSERT(:associate_array, 'abc', 4, true);
    
      CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(OBJECT_KEYS(:associate_array)));
      
      FOR i IN 1 TO ARRAY_SIZE(OBJECT_KEYS(:associate_array))
      LOOP
         associate_index := OBJECT_KEYS(:associate_array)[:i-1];
         CALL DBMS_OUTPUT.PUT_LINE(:associate_array[:associate_index]);
      END LOOP;
   END;
$$;

CALL PUBLIC.associative_array();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

1

3

4

2

3

数値インデックス付き連想配列

Oracle
CREATE OR REPLACE PROCEDURE numeric_associative_array
IS
    TYPE numeric_associative_array_typ IS TABLE OF INTEGER
        INDEX BY PLS_INTEGER;
        
    associate_array numeric_associativ
    e_array_typ := numeric_associative_array_typ();
    associate_index PLS_INTEGER;
BEGIN
    associate_array(1) := -1;
    associate_array(2) := -2;
    associate_array(3) := -3;
    
    DBMS_OUTPUT.PUT_LINE(associate_array(1));
    associate_array(1) := -4;
    
    DBMS_OUTPUT.PUT_LINE(associate_array.COUNT);
    
    associate_index := associate_array.FIRST;
    WHILE associate_index IS NOT NULL
    LOOP
        DBMS_OUTPUT.PUT_LINE(associate_array(associate_index));
        associate_index := associate_array.NEXT(associate_index);
    END LOOP;
END;

CALL numeric_associative_array();
Copy
結果

DBMS に OUTPUT

-1

3

-4

-2

-3

Snowflake

数値は、操作が必要とするときに適宜varcharに変換されることに注意してください。さらに、 OBJECT_INSERT の「true」パラメーターに注意してください。これは、その要素がすでに配列内に存在する場合に、その要素が更新されるようにするためです。

CREATE OR REPLACE PROCEDURE PUBLIC.numeric_associative_array ()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
   DECLARE
      associate_array OBJECT := OBJECT_CONSTRUCT();
      associate_index NUMBER;
   BEGIN
      associate_array := OBJECT_INSERT(associate_array, '1', -1, true);
      associate_array := OBJECT_INSERT(associate_array, '2', -2, true);
      associate_array := OBJECT_INSERT(associate_array, '3', -3, true);

      CALL DBMS_OUTPUT.PUT_LINE(:associate_array['1']);
      
      associate_array := OBJECT_INSERT(:associate_array, '1', -4, true);
    
      CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(OBJECT_KEYS(:associate_array)));
      
      FOR i IN 1 TO ARRAY_SIZE(OBJECT_KEYS(:associate_array))
      LOOP
         associate_index := OBJECT_KEYS(:associate_array)[:i-1];
         CALL DBMS_OUTPUT.PUT_LINE(:associate_array[:associate_index::VARCHAR]);
      END LOOP;
   END;
$$;

CALL PUBLIC.numeric_associative_array();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

-1

3

-4

-2

-3

記録要素数値インデックス付き連想配列

この場合、連想配列は記録構造で構成されており、この構造を保持する必要があります。そのために、挿入に関する操作がさらに追加されました。

Oracle
CREATE OR REPLACE PROCEDURE record_associative_array
IS
    TYPE record_typ IS RECORD(col1 INTEGER);
    TYPE record_associative_array_typ IS TABLE OF record_typ
        INDEX BY PLS_INTEGER;
        
    associate_array record_associati ve_array_typ := record_associative_array_typ();
    associate_index PLS_INTEGER;
BEGIN
    associate_array(1).col1 := -1;
    associate_array(2).col1 := -2;
    associate_array(3).col1 := -3;
    
    DBMS_OUTPUT.PUT_LINE(associate_array(1).col1);
    associate_array(4).col1 := -4;
    
    DBMS_OUTPUT.PUT_LINE(associate_array.COUNT);
    
    associate_index := associate_array.FIRST;
    WHILE associate_index IS NOT NULL
    LOOP
        DBMS_OUTPUT.PUT_LINE(associate_array(associate_index).col1);
        associate_index := associate_array.NEXT(associate_index);
    END LOOP;
END;
/

CALL record_associative_array();
Copy
結果

DBMS に OUTPUT

-1

3

-4

-2

-3

Snowflake

このシナリオでは、挿入/更新は、連想配列内の記録の自動作成を想定しており、新しい記録を作成するときにこれを考慮する必要があります。

CREATE OR REPLACE PROCEDURE PUBLIC.record_associative_array ()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
   DECLARE
      associate_array OBJECT := OBJECT_CONSTRUCT();
      associate_index NUMBER;
   BEGIN
      associate_array := OBJECT_INSERT(associate_array, '1', OBJECT_INSERT(NVL(associate_array['1'], OBJECT_CONSTRUCT()), 'col1', -1, true), true);
      associate_array := OBJECT_INSERT(associate_array, '2', OBJECT_INSERT(NVL(associate_array['2'], OBJECT_CONSTRUCT()), 'col1', -2, true), true);
      associate_array := OBJECT_INSERT(associate_array, '3', OBJECT_INSERT(NVL(associate_array['3'], OBJECT_CONSTRUCT()), 'col1', -3, true), true);

      CALL DBMS_OUTPUT.PUT_LINE(:associate_array['1']:col1);
      
      associate_array := OBJECT_INSERT(associate_array, '1', OBJECT_INSERT(NVL(associate_array['1'], OBJECT_CONSTRUCT()), 'col1', -4, true), true);
    
      CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(OBJECT_KEYS(:associate_array)));
      
      FOR i IN 1 TO ARRAY_SIZE(OBJECT_KEYS(:associate_array))
      LOOP
         associate_index := OBJECT_KEYS(:associate_array)[:i-1];
         CALL DBMS_OUTPUT.PUT_LINE(:associate_array[:associate_index::VARCHAR]:col1);
      END LOOP;
   END;
$$;

CALL PUBLIC.record_associative_array();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

-1

3

-4

-2

-3

既知の問題

1.現在は認識されていません

SnowConvert AI はこれらのコレクションをネストされたテーブル配列として扱います。これを修正するための作業アイテムがあります。

関連 EWIs

関連 EWIs はありません。

コレクションメソッド

これは、OracleコレクションメソッドをSnowflakeに変換するための変換リファレンスです

警告

このセクションは進行中であり、情報は将来変更される可能性があります

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

コレクションメソッドは、 PL/SQL サブプログラムで、コレクションに関する情報を返す関数、またはコレクションを操作するプロシージャです。コレクションメソッドは、コレクションを使いやすくし、アプリケーションを保守しやすくします。

(Oracle PL/SQL 言語リファレンス COLLECTION METHODS)

これらのメソッドの一部は、ネイティブのSnowflake半構造化操作にマッピングできます。できないもの、あるいは違いがあるものは、 UDF の実装にマッピングされます。

現在の SnowConvert AI サポート

次の表は、 SnowConvert AI ツールで現在提供されているサポートの概要を示しています。変換がまだ最終的なものではない可能性があること、さらに作業が必要になる可能性があることにご注意ください。

メソッド

現在の認識ステータス

現在の変換ステータス

マッピング先

[DELETE](#delete)

認識されません。

変換されていません。

UDF

[TRIM](#trim)

認識されません。

変換されていません。

UDF (定義予定)

[EXTEND](#extend)

認識されません。

変換されていません。

UDF

[EXISTS](#exists)

認識されません。

変換されていません。

[ARRAY_CONTAINS](https://docs.snowflake.com/en/sql-reference/functions/array_contains.html)

[FIRST](#firstlast)

認識されません。

変換されていません。

UDF

[LAST](#firstlast)

認識されません。

変換されていません。

UDF

[COUNT](#count)

認識されません。

変換されていません。

[ARRAY_SIZE](https://docs.snowflake.com/en/sql-reference/functions/array_size.html)

[LIMIT](#limit)

認識されません。

変換されていません。

サポート対象外です。

[PRIOR](#priornext)

認識されません。

変換されていません。

UDF (定義予定)

[NEXT](#priornext)

認識されません。

変換されていません。

UDF (定義予定)

サンプルソースパターン

COUNT

このメソッドは、コレクション内の「未定義ではない」(nullと混同しないでください)要素の数を返します(ネストされたテーブルは、これらの要素が間に残ったまままばらになることがあります)。連想配列では、配列内のキーの数を返します。

Oracle
CREATE OR REPLACE PROCEDURE collection_count
IS
    TYPE varray_typ IS VARRAY(5) OF INTEGER;
    TYPE nt_typ IS TABLE OF INTEGER;
    TYPE aa_typ IS TABLE OF INTEGER INDEX BY VARCHAR2(20);
    
    associative_array aa_typ := aa_typ('abc'=>1, 'bca'=>1);
    varray_variable varray_typ := varray_typ(1, 2, 3);
    nt_variable nt_typ := nt_typ(1, 2, 3, 4);
BEGIN
    DBMS_OUTPUT.PUT_LINE(associative_array.COUNT);
    DBMS_OUTPUT.PUT_LINE(varray_variable.COUNT);
    DBMS_OUTPUT.PUT_LINE(nt_variable.COUNT);
END;

CALL collection_count();
Copy
結果

DBMS に OUTPUT

2

3

4

Snowflake

Snowflakeの同等のものは、 ARRAY_SIZE メソッドです。

CREATE OR REPLACE PROCEDURE PUBLIC.collection_count()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    associative_array OBJECT := OBJECT_CONSTRUCT('abc', 1, 'bca', 1);
    varray_variable ARRAY := ARRAY_CONSTRUCT(1, 2, 3);
    nt_variable ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
BEGIN
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(OBJECT_KEYS(:associative_array)));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(:varray_variable));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(:nt_variable));
END;
$$;

CALL PUBLIC.collection_count();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

2

3

4

EXISTS

このメソッドは、指定された要素がコレクション内に含まれる場合にtrueを返します。連想配列では、キーが含まれているかどうかを調べます。

Oracle
CREATE OR REPLACE PROCEDURE collection_exists
IS
    TYPE nt_typ IS TABLE OF INTEGER;
    TYPE aa_typ IS TABLE OF INTEGER INDEX BY VARCHAR2(20);
    
    associative_array aa_typ := aa_typ('abc'=>1, 'bca'=>1);
    nt_variable nt_typ := nt_typ(1, 2, 3, 4);
BEGIN
    IF associative_array.EXISTS('abc')
    THEN DBMS_OUTPUT.PUT_LINE('Found');
    END IF;
    
    IF NOT associative_array.EXISTS('not found')
    THEN DBMS_OUTPUT.PUT_LINE('Not found');
    END IF;
    
    IF nt_variable.EXISTS(1)
    THEN DBMS_OUTPUT.PUT_LINE('Found');
    END IF;
    
    IF NOT nt_variable.EXISTS(5)
    THEN DBMS_OUTPUT.PUT_LINE('Not found');
    END IF;
END;
/

CALL collection_exists();
Copy
結果

DBMS に OUTPUT

2

3

4

Snowflake

Snowflakeの同等のものは、 ARRAY_CONTAINS メソッドです。Varchar要素を使用する場合は、バリアントへのキャストが必要であることに注意してください。

CREATE OR REPLACE PROCEDURE PUBLIC.collection_exists()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    associative_array OBJECT := OBJECT_CONSTRUCT('abc', 1, 'bca', 1);
    nt_variable ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
BEGIN
    IF (ARRAY_CONTAINS('abc'::VARIANT, OBJECT_KEYS(associative_array)))
    THEN CALL DBMS_OUTPUT.PUT_LINE('Found');
    END IF;
    
    IF (NOT ARRAY_CONTAINS('not found'::VARIANT, OBJECT_KEYS(associative_array)))
    THEN CALL DBMS_OUTPUT.PUT_LINE('Not found');
    END IF;
    
    IF (ARRAY_CONTAINS(1, nt_variable))
    THEN CALL DBMS_OUTPUT.PUT_LINE('Found');
    END IF;
    
    IF (NOT ARRAY_CONTAINS(5, nt_variable))
    THEN CALL DBMS_OUTPUT.PUT_LINE('Not found');
    END IF;
END;
$$;

CALL PUBLIC.collection_exists();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

2

3

4

FIRST/LAST

この2つのメソッドは、それぞれコレクションの最初と最後の要素を返します。コレクションが空の場合はnullを返します。この操作は UDF にマッピングされており、今後の改訂で追加される予定です。

Oracle
CREATE OR REPLACE PROCEDURE collection_first_last
IS
    TYPE nt_typ IS TABLE OF INTEGER;
    TYPE aa_typ IS TABLE OF INTEGER INDEX BY VARCHAR2(20);
    
    associative_array aa_typ := aa_typ('abc'=>1, 'bca'=>1);
    nt_variable nt_typ := nt_typ();
BEGIN
    DBMS_OUTPUT.PUT_LINE(associative_array.FIRST);
    DBMS_OUTPUT.PUT_LINE(associative_array.LAST);
    
    DBMS_OUTPUT.PUT_LINE(nt_variable.FIRST);
    DBMS_OUTPUT.PUT_LINE(nt_variable.LAST);
    nt_variable := nt_typ(1, 2, 3, 4);
    DBMS_OUTPUT.PUT_LINE(nt_variable.FIRST);
    DBMS_OUTPUT.PUT_LINE(nt_variable.LAST);
END;
/

CALL collection_first_last();
Copy
結果

DBMS に OUTPUT

abc

bca

--これらの空白はnullと評価されたために発生します

1

4

Snowflake
CREATE OR REPLACE PROCEDURE PUBLIC.collection_first_last()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    associative_array OBJECT := OBJECT_CONSTRUCT('abc', 1, 'bca', 1);
    nt_variable ARRAY := ARRAY_CONSTRUCT();
BEGIN
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_FIRST(:associative_array));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_LAST(:associative_array));
    
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_FIRST(:nt_variable));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_LAST(:nt_variable));
    nt_variable := ARRAY_CONSTRUCT(1, 2, 3, 4);
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_FIRST(:nt_variable));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_LAST(:nt_variable));
END;
$$;

CALL PUBLIC.collection_first_last();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
UDFs
CREATE OR REPLACE FUNCTION ARRAY_FIRST(array_variable VARIANT)
RETURNS VARIANT
LANGUAGE SQL
AS
$$
    IFF (IS_OBJECT(array_variable),
        ARRAY_FIRST(OBJECT_KEYS(array_variable)),
        IFF (ARRAY_SIZE(array_variable) = 0, null, array_variable[0]))
$$;

CREATE OR REPLACE FUNCTION ARRAY_LAST(array_variable VARIANT)
RETURNS VARIANT
LANGUAGE SQL
AS
$$
    IFF (IS_OBJECT(array_variable),
        ARRAY_LAST(OBJECT_KEYS(array_variable)),
        IFF (ARRAY_SIZE(array_variable) = 0, null, array_variable[ARRAY_SIZE(array_variable)-1]))
$$;
Copy
結果

DBMS に OUTPUT

abc

bca

--これらの空白はnullと評価されたために発生します

1

4

DELETE

このメソッドは、コレクションから要素を削除するために使用します。バリアントは3種類あります。

  • .DELETE はすべての要素を削除します。

  • .DELETE(n)はインデックスが「n」にマッチする要素を削除します。

  • .DELETE(n, m)は、「n」から「m」までのインデックスを削除します。

注釈

Oracleでは、ネストされたテーブルに対してこの操作を使用すると、テーブル内の要素がまばらであるために「未定義」になります。

警告

第2、第3バージョンはVarraysには適用されませんのでご注意ください。

Oracle

簡潔にするため、このサンプルでは要素数のみをチェックしていますが、各コレクションの内容を表示するように変更することもできます。

CREATE OR REPLACE PROCEDURE collection_delete
IS
    TYPE varray_typ IS VARRAY(5) OF INTEGER;
    TYPE nt_typ IS TABLE OF INTEGER;
    TYPE aa_typ IS TABLE OF INTEGER INDEX BY VARCHAR2(20);
    
    associative_array1 aa_typ := aa_typ('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
    associative_array2 aa_typ := aa_typ('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
    associative_array3 aa_typ := aa_typ('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
    
    varray_variable1 varray_typ := varray_typ(1, 2, 3, 4);
    
    nt_variable1 nt_typ := nt_typ(1, 2, 3, 4);
    nt_variable2 nt_typ := nt_typ(1, 2, 3, 4);
    nt_variable3 nt_typ := nt_typ(1, 2, 3, 4);
BEGIN
    varray_variable1.DELETE;--delete everything
    
    nt_variable1.DELETE;--delete everything
    nt_variable2.DELETE(2);--delete second position
    nt_variable3.DELETE(2, 3);--delete range
    
    associative_array1.DELETE;--delete everything
    associative_array2.DELETE('def');--delete second position
    associative_array3.DELETE('def', 'jkl');--delete range
    
    DBMS_OUTPUT.PUT_LINE(varray_variable1.COUNT);
    DBMS_OUTPUT.PUT_LINE(nt_variable1.COUNT);
    DBMS_OUTPUT.PUT_LINE(nt_variable2.COUNT);
    DBMS_OUTPUT.PUT_LINE(nt_variable3.COUNT);
    
    DBMS_OUTPUT.PUT_LINE(associative_array1.COUNT);
    DBMS_OUTPUT.PUT_LINE(associative_array2.COUNT);
    DBMS_OUTPUT.PUT_LINE(associative_array3.COUNT);
END;
/

CALL collection_delete();
Copy
結果

DBMS に OUTPUT

0

0

3

2

0

3

1

Snowflake

Snowflakeは既存の ARRAY からの削除をサポートしていません。このため、唯一の回避策は、 DELETE の元のパラメーターに応じて新しい ARRAY を再構築することです。

注釈

要素の更新のための機能を実装するために UDF が追加されたことに注意してください。

この UDF は、後の改訂で追加される予定です。

CREATE OR REPLACE PROCEDURE PUBLIC.collection_delete()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    associative_array1 OBJECT := OBJECT_CONSTRUCT('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
    associative_array2 OBJECT := OBJECT_CONSTRUCT('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
    associative_array3 OBJECT := OBJECT_CONSTRUCT('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
    
    varray_variable1 ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
    
    nt_variable1 ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
    nt_variable2 ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
    nt_variable3 ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
BEGIN
    varray_variable1 := ARRAY_CONSTRUCT();--delete everything
    
    nt_variable1 := ARRAY_CONSTRUCT();--delete everything
    nt_variable2 := ARRAY_DELETE_UDF(nt_variable2, 2);--delete second position
    nt_variable3 := ARRAY_DELETE_UDF(nt_variable3, 2, 3);--delete range
    
    associative_array1 := OBJECT_CONSTRUCT();--delete everything
    associative_array2 := ASSOCIATIVE_ARRAY_DELETE_UDF('def');--delete second position
    associative_array3 := ASSOCIATIVE_ARRAY_DELETE_UDF('def', 'jkl');--delete range
    
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(varray_variable1));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(nt_variable1);
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(nt_variable2);
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(nt_variable3);
    
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(associative_array1));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(associative_array2));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(associative_array3));
END;
$$;

CALL PUBLIC.collection_first_last();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

0

0

3

2

0

3

1

EXTEND

このメソッドは、ネストされたテーブルまたはVarrayに新しい要素を追加するために使用します。バリアントは3種類あります。

  • .EXTEND はnull要素を挿入します。

  • .EXTEND(n)は「n」個のnull要素を挿入します。

  • .EXTEND(n, i)は、「i」に要素のコピーを「n」個挿入します。

Oracle
CREATE OR REPLACE PROCEDURE collection_extend
IS 
    TYPE varray_typ IS VARRAY(5) OF INTEGER;
    TYPE nt_typ IS TABLE OF INTEGER;
    
    nt_variable1 nt_typ := nt_typ(1, 2, 3, 4);
    varray_variable1 varray_typ := varray_typ(1, 2, 3);
    varray_variable2 varray_typ := varray_typ(1, 2, 3);
BEGIN
    nt_variable1.EXTEND;
    varray_variable1.EXTEND(2);
    varray_variable2.EXTEND(2, 1);
    
    DBMS_OUTPUT.PUT_LINE(nt_variable1.COUNT);
    DBMS_OUTPUT.PUT_LINE(varray_variable1.COUNT);
    DBMS_OUTPUT.PUT_LINE(varray_variable2.COUNT);
END;
/

CALL collection_extend();
Copy
結果

DBMS に OUTPUT

5

5

5

Snowflake

注釈

要素の更新のための機能を実装するために UDF が追加されたことに注意してください。

この UDF は、後の改訂で追加される予定です。

CREATE OR REPLACE PROCEDURE PUBLIC.collection_first_last()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    nt_variable1 ARRAY := ARRAY_CONSTRUCT(1, 2, 3, 4);
    varray_variable1 ARRAY := ARRAY_CONSTRUCT(1, 2, 3);
    varray_variable2 ARRAY := ARRAY_CONSTRUCT(1, 2, 3);
BEGIN
    nt_variable1 := ARRAY_EXTEND_UDF(nt_variable);
    varray_variable1 := ARRAY_EXTEND_UDF(varray_variable1, 2);
    varray_variable2 := ARRAY_EXTEND_UDF(varray_variable2, 2, 1);
    
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(nt_variable1);
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(varray_variable1));
    CALL DBMS_OUTPUT.PUT_LINE(ARRAY_SIZE(varray_variable2));
END;
$$;

CALL PUBLIC.collection_first_last();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
結果

DBMS に OUTPUT

5

5

5

TRIM

このメソッドは、ネストされたテーブルやVarrayから最後の要素を削除するために使用します。バリアントには2種類あります。

  • .TRIM は最後の要素を削除します。

  • .TRIM(n)は最後の「n」個の要素を削除します。

注釈

この機能は、 ARRAY_SLICE を使用して実装できます。

Oracle
CREATE OR REPLACE PROCEDURE collection_trim
IS 
    TYPE varray_typ IS VARRAY(5) OF INTEGER;
    TYPE nt_typ IS TABLE OF INTEGER;
    
    varray_variable1 varray_typ := varray_typ(1, 2, 3);
    nt_variable1 nt_typ := nt_typ(1, 2, 3, 4);
BEGIN
    varray_variable1.TRIM;
    nt_variable1.TRIM(2);
    
    DBMS_OUTPUT.PUT_LINE(nt_variable1.COUNT);
    DBMS_OUTPUT.PUT_LINE(varray_variable1.COUNT);
END;
/

CALL collection_trim();
Copy
結果
DBMS OUTPUT
-----------
2
2

Copy

LIMIT

このメソッドはVarrayの上限を返します。

危険

このメソッドはSnowflakeではサポートされていません。

Oracle
CREATE OR REPLACE PROCEDURE collection_limit
IS 
    TYPE varray_typ1 IS VARRAY(5) OF INTEGER;
    TYPE varray_typ2 IS VARRAY(6) OF INTEGER;
    
    varray_variable1 varray_typ1 := varray_typ1(1, 2, 3);
    varray_variable2 varray_typ2 := varray_typ2(1, 2, 3, 4);
BEGIN
    DBMS_OUTPUT.PUT_LINE(varray_variable1.LIMIT);
    DBMS_OUTPUT.PUT_LINE(varray_variable2.LIMIT);
END;
/

CALL collection_limit();
Copy
結果

DBMS に OUTPUT

5

6

PRIOR/NEXT

このメソッドは、インデックスを指定すると、その前後のインデックスを返します。先行/後続がない場合はnullを返します。コレクションをたどるときによく使われます。

Oracle
CREATE OR REPLACE PROCEDURE collection_prior_next
IS 
    TYPE varray_typ1 IS VARRAY(5) OF INTEGER;
    TYPE aa_typ IS TABLE OF INTEGER INDEX BY VARCHAR2(20);
    
    varray_variable1 varray_typ1 := varray_typ1(-1, -2, -3);
    associative_array1 aa_typ := aa_typ('abc'=>1, 'def'=>2, 'ghi'=>3, 'jkl'=>4);
BEGIN
    DBMS_OUTPUT.PUT_LINE(varray_variable1.PRIOR(1));
    DBMS_OUTPUT.PUT_LINE(varray_variable1.PRIOR(2));
    DBMS_OUTPUT.PUT_LINE(varray_variable1.NEXT(2));
    DBMS_OUTPUT.PUT_LINE(varray_variable1.NEXT(3));
    
    DBMS_OUTPUT.PUT_LINE(associative_array1.PRIOR('abc'));
    DBMS_OUTPUT.PUT_LINE(associative_array1.PRIOR('def'));
    DBMS_OUTPUT.PUT_LINE(associative_array1.NEXT('ghi'));
    DBMS_OUTPUT.PUT_LINE(associative_array1.NEXT('jkl'));
    DBMS_OUTPUT.PUT_LINE(associative_array1.PRIOR('not found'));
END;
/

CALL collection_prior_next();
Copy
結果

DBMS に OUTPUT

-- 空白部分は結果が空であるためです

1

3

abc

jkl

jkl

既知の問題

1.LimitメソッドはSnowflakeではサポートされていません

Snowflakeは、スペースが制限されたvarrayをサポートしていません。そのため、このメソッドはサポートされていません。

関連 EWIs

関連する EWIs なし。

ネストされたテーブル配列型定義

これは、Oracleのネストされたテーブル配列宣言をSnowflakeに変換するための変換リファレンスです。

警告

このセクションは進行中であり、情報は将来変更される可能性があります。

注釈

このセクションは、ネストされたテーブル配列の PL/SQL バージョンに関するものです。スタンドアロンバージョンについては、[ネストされたテーブル型の定義](../sql-translation-reference/create_type.md#nested-table-type-definition)を参照してください。

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

データベースでは、ネストされたテーブルは、不特定多数の行を順不同に格納する列型です。

データベースから PL/SQL ネストされたテーブル変数にネストされたテーブル値を取り出すと、 PL/SQL は1から始まる連続したインデックスを行に与えます。これらのインデックスを使用すると、ネストされたテーブル変数の個々の行にアクセスできます。構文は variable_name(index) です。データベースからネストされたテーブルを格納したり取得したりする際に、ネストされたテーブルのインデックスや行の順序が安定しない可能性があります。

(Oracle PL/SQL 言語リファレンス NESTED TABLES)

翻訳のために、型定義は ARRAY 半構造化データ型 に置き換えられ、その使用はあらゆる操作にわたって適宜変更されます。ネストされたテーブルとVarraysの翻訳が同じであることに注意してください。

ネストされたテーブル配列型を定義するための構文は以下の通りです。

type_definition := TYPE IS TABLE OF datatype;

Copy

この型の変数を宣言するには

variable_name collection_type;

Copy

サンプルソースパターン

ネストされたテーブル配列の定義

これは、異なるネストされたテーブル配列を作成する方法と、変数の定義を移行する方法を示しています。

Oracle
CREATE OR REPLACE PROCEDURE nested_table_procedure
IS
    TYPE nested_table_array_typ IS TABLE OF INTEGER;
    TYPE nested_table_array_typ2 IS TABLE OF DATE;
    
    nested_table_array nested_table_array_typ;
    nested_table_array2 nested_table_array_typ2;
BEGIN
    NULL;
END;
Copy
Snowflake
CREATE OR REPLACE PROCEDURE nested_table_procedure()
RETURNS INTEGER
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    -- NO LONGER NEEDED
    /*
    TYPE associative_array_typ IS TABLE OF INTEGER INDEX BY VARCHAR2(30);
    TYPE associative_array_typ2 IS TABLE OF INTEGER INDEX BY PLS_INTEGER;
    */
    
    associative_array ARRAY;
    associative_array2 ARRAY;
BEGIN
    NULL;
END;
$$;
Copy

ネストされたテーブルの繰り返し

Oracle
CREATE OR REPLACE PROCEDURE nested_table_iteration
IS
    TYPE nested_table_typ IS TABLE OF INTEGER;
    nested_table_variable nested_table_typ := nested_table_typ (10, 20, 30);
BEGIN
    FOR i IN 1..nested_table_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(nested_table_variable(i));
    END LOOP;
    
    nested_table_variable (1) := 40;
    
    FOR i IN 1..nested_table_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(nested_table_variable(i));
    END LOOP;
END;
/

CALL nested_table_iteration();
Copy
結果

DBMS に OUTPUT

10

20

30

40

20

30

Snowflake

注釈

要素の更新のための機能を実装するために UDF が追加されたことに注意してください。

この UDF は、後の改訂で追加される予定です。

CREATE OR REPLACE PROCEDURE PUBLIC.nested_table_iteration()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
    nested_table_variable ARRAY := ARRAY_CONSTRUCT(10, 20, 30);
BEGIN
    FOR i IN 1 TO ARRAY_SIZE(nested_table_variable)
    LOOP
        CALL DBMS_OUTPUT.PUT_LINE(:nested_table_variable[:i-1]);
    END LOOP;

    nested_table_variable:= INSERT_REPLACE_COLLECTION_ELEMENT_UDF(nested_table_variable, 1, 40);
    
    FOR i IN 1 TO ARRAY_SIZE(nested_table_variable)
    LOOP
        CALL DBMS_OUTPUT.PUT_LINE(:nested_table_variable[:i-1]);
    END LOOP;
END;
$$;

CALL PUBLIC.nested_table_iteration();
SELECT * FROM DBMS_OUTPUT.DBMS_OUTPUT_LOG;
Copy
UDF
CREATE OR REPLACE FUNCTION PUBLIC.INSERT_REPLACE_COLLECTION_ELEMENT_UDF(varray ARRAY, position INTEGER, newValue VARIANT)
RETURNS ARRAY
LANGUAGE SQL
AS
$$
    ARRAY_CAT(
        ARRAY_APPEND(ARRAY_SLICE(varray, 0, (position)-1), newValue),
        ARRAY_SLICE(varray, position, ARRAY_SIZE(varray)))
$$;
Copy
結果

DBMS に OUTPUT

10

20

30

40

20

30

既知の問題

1.現在、変換されていません

SnowConvert AI はこれらの要素の変換をサポートしていません。

2.インデックスの修正が必要です

Oracleのインデックスは1から始まりますが、Snowflakeでは0から始まります。

関連 EWIs

関連する EWIs なし。

記録型定義

これは、Oracleの記録宣言をSnowflakeに変換するための変換リファレンスです。

警告

このセクションは進行中であり、情報は将来変更される可能性があります。

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

記録変数は、フィールドと呼ばれる内部コンポーネントが異なるデータ型を持つことができる複合変数です。記録変数の値とそのフィールドの値は変更可能です。

記録変数全体をその名前で参照します。record.field という構文で記録フィールドを参照します。

記録変数はこれらの方法で作成できます。

  • 記録型を定義し、その型の変数を宣言します。

  • %ROWTYPE を使用して、データベーステーブルまたはビューの完全行または部分行を表す記録変数を宣言します。

  • %TYPE を使用して、以前に宣言された記録変数と同じ型の記録変数を宣言します。

(Oracle PL/SQL 言語リファレンス RECORD VARIABLES)

翻訳のために、型定義は OBJECT 半構造化データ型 に置き換えられ、その使用はあらゆる操作にわたって適宜変更されます。

記録型を定義するための構文は以下の通りです。

type_definition := TYPE IS RECORD ( field_definition [, field_definition...] );

field_definition := field_name datatype [ { [NOT NULL default ] | default } ]

default := [ { := | DEFAULT } expression]

Copy

この型の変数を宣言するには

variable_name { record_type
              | rowtype_attribute
              | record_variable%TYPE
              };

Copy

サンプルソースパターン

注釈

わかりやすくするため、出力コードの一部を省略しています。

記録の初期化と割り当て

このサンプルは、プロシージャの途中で再割り当てされる記録変数を使用して、2つの新しい行を挿入しようとしています。

Oracle
CREATE TABLE record_table(col1 FLOAT, col2 INTEGER);

CREATE OR REPLACE PROCEDURE record_procedure
IS
    TYPE record_typ IS RECORD(col1 INTEGER, col2 FLOAT);
    record_variable record_typ := record_typ(1, 1.5);--initialization
BEGIN
    INSERT INTO record_table(col1, col2)
        VALUES (record_variable.col2, record_variable.col1);--usage
        
    --reassignment of properties
    record_variable.col1 := 2;
    record_variable.col2 := 2.5;
    
    INSERT INTO record_table(col1, col2)
        VALUES (record_variable.col2, record_variable.col1);--usage
END;

CALL record_procedure();
SELECT * FROM record_table;
Copy
結果

COL1

COL2

1.5

1

2.5

2

Snowflake

再割り当てが、列が既に存在する場合に更新する OBJECT_INSERT で置き換えられ、 VALUES 句が SELECT で置き換えられていることに注意してください。

CREATE OR REPLACE TABLE record_table (col1 FLOAT,
    col2 INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

CREATE OR REPLACE PROCEDURE record_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        !!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO OBJECT ***/!!!
        TYPE record_typ IS RECORD(col1 INTEGER, col2 FLOAT);
        record_variable OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - record_typ DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT('COL1', 1, 'COL2', 1.5);--initialization

    BEGIN
        INSERT INTO record_table(col1, col2)
        SELECT
            :record_variable:COL2,
            :record_variable:COL1;--usage

        --reassignment of properties
        record_variable := OBJECT_INSERT(record_variable, 'COL1', 2, true);
        record_variable := OBJECT_INSERT(record_variable, 'COL2', 2.5, true);

        INSERT INTO record_table(col1, col2)
        SELECT
            :record_variable:COL2,
            :record_variable:COL1;--usage

    END;
$$;

CALL record_procedure();

SELECT * FROM
    record_table;
Copy
結果

COL1

COL2

1.5

1

2.5

2

%ROWTYPE Record and Values Record

操作は構造を定義するものであるため、これらの定義は OBJECT データ型に置き換えることができますが、記録を「そのまま」挿入することはサポートされていないため、記録の値を分解する必要があります。

Oracle
CREATE TABLE record_table(col1 INTEGER, col2 VARCHAR2(50), col3 DATE);
CREATE OR REPLACE PROCEDURE insert_record
IS
    record_variable record_table%ROWTYPE;
BEGIN
    record_variable.col1 := 1;
    record_variable.col2 := 'Hello';
    record_variable.col3 := DATE '2020-12-25';
    
    INSERT INTO record_table VALUES record_variable;
END;

CALL insert_record();
SELECT * FROM record_table;
Copy
結果

COL1

COL2

COL3

1

"Hello"

25-DEC-20

Snowflake

最後に、情報を追加するために変数 OBJECT を初期化する必要があることに注意してください。

CREATE OR REPLACE TABLE record_table (col1 INTEGER,
    col2 VARCHAR(50),
    col3 TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;

CREATE OR REPLACE PROCEDURE insert_record ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        record_variable OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - ROWTYPE DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();
    BEGIN
        record_variable := OBJECT_INSERT(record_variable, 'COL1', 1, true);
        record_variable := OBJECT_INSERT(record_variable, 'COL2', 'Hello', true);
        record_variable := OBJECT_INSERT(record_variable, 'COL3', DATE '2020-12-25', true);
        INSERT INTO record_table
        SELECT
            :record_variable:COL1,
            :record_variable:COL2,
            :record_variable:COL3;
    END;
$$;

CALL insert_record();

SELECT * FROM
    record_table;
Copy
結果

COL1

COL2

COL3

1

"Hello"

25-DEC-20

記録へのデータ取得

Oracle
CREATE TABLE record_table(col1 INTEGER, col2 VARCHAR2(50), col3 DATE);
INSERT INTO record_table(col1, col2 , col3)
    VALUES (1, 'Hello', DATE '2020-12-25');

CREATE OR REPLACE PROCEDURE load_cursor_record
IS
    CURSOR record_cursor IS
        SELECT *
        FROM record_table;
        
    record_variable record_cursor%ROWTYPE;
BEGIN
    OPEN record_cursor;
    LOOP
        FETCH record_cursor INTO record_variable;
        EXIT WHEN record_cursor%NOTFOUND;
        
        DBMS_OUTPUT.PUT_LINE(record_variable.col1);
        DBMS_OUTPUT.PUT_LINE(record_variable.col2);
        DBMS_OUTPUT.PUT_LINE(record_variable.col3);
    END LOOP;
    CLOSE record_cursor;
END;

CALL load_cursor_record();
Copy
結果

DBMS に OUTPUT

1

Hello

25-DEC-20

Snowflake

カーソル定義に OBJECT_CONSTRUCT が追加されていることに注意してください。これは OBJECT を抽出するためのもので、これを使用して FETCH ステートメントをシームレスに移行できます。

CREATE OR REPLACE TABLE record_table (col1 INTEGER,
    col2 VARCHAR(50),
    col3 TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;

INSERT INTO record_table(col1, col2 , col3)
    VALUES (1, 'Hello', DATE '2020-12-25');

CREATE OR REPLACE PROCEDURE load_cursor_record ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        --** SSC-PRF-0009 - PERFORMANCE REVIEW - CURSOR USAGE **
        record_cursor CURSOR
        FOR
            SELECT
                OBJECT_CONSTRUCT( *) sc_cursor_record
            FROM
                record_table;
    record_variable OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - ROWTYPE DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();
    BEGIN
        OPEN record_cursor;
        --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
    LOOP
            --** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
        FETCH record_cursor INTO
                :record_variable;
        IF (record_variable IS NULL) THEN
                EXIT;
        END IF;
        --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
        CALL DBMS_OUTPUT.PUT_LINE_UDF(:record_variable:COL1);
        --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
        CALL DBMS_OUTPUT.PUT_LINE_UDF(:record_variable:COL2);
        --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
        CALL DBMS_OUTPUT.PUT_LINE_UDF(:record_variable:COL3::DATE);
    END LOOP;
    CLOSE record_cursor;
    END;
$$;

CALL load_cursor_record();
Copy
結果

DBMS に OUTPUT

1

Hello

25-DEC-20

SELECT INTO への記録変数の割り当て

この変換は、 SELECT 列を引数として記録を初期化する OBJECT୧_CONTRUCT 関数を利用することで行われます。

補助コードのサンプル

Oracle
create table sample_table(ID number, NAME varchar2(23));
CREATE TABLE RESULTS (COL1 VARCHAR(20), COL2 VARCHAR(40));
insert into sample_table values(1, 'NAME 1');
insert into sample_table values(2, 'NAME 2');
insert into sample_table values(3, 'NAME 3');
insert into sample_table values(4, 'NAME 4');
Copy
Snowflake
CREATE OR REPLACE TABLE sample_table (ID NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
NAME VARCHAR(23))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

CREATE OR REPLACE TABLE RESULTS (COL1 VARCHAR(20),
COL2 VARCHAR(40))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

insert into sample_table
values(1, 'NAME 1');

insert into sample_table
values(2, 'NAME 2');

insert into sample_table
values(3, 'NAME 3');

insert into sample_table
values(4, 'NAME 4');
Copy
Oracle
CREATE OR REPLACE PROCEDURE sp_sample1 AS
-- Rowtype variable
rowtype_variable sample_table%rowtype;

--Record variable
TYPE record_typ_def IS RECORD(ID number, NAME varchar2(23));
record_variable_def record_typ_def;

-- Auxiliary variable
name_var VARCHAR(20);
BEGIN
   SELECT * INTO rowtype_variable FROM sample_table WHERE ID = 1 FETCH NEXT 1 ROWS ONLY;
   name_var := rowtype_variable.NAME;
   INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 1', name_var);
  
   SELECT ID, NAME INTO rowtype_variable FROM sample_table WHERE ID = 2 FETCH NEXT 1 ROWS ONLY;
   name_var := rowtype_variable.NAME;
   INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 2', name_var);
  
   SELECT * INTO record_variable_def FROM sample_table WHERE ID = 3 FETCH NEXT 1 ROWS ONLY;
   name_var := record_variable_def.NAME;
   INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 3', name_var);
  
   SELECT ID, NAME INTO record_variable_def FROM sample_table WHERE ID = 4 FETCH NEXT 1 ROWS ONLY;
   name_var := record_variable_def.NAME;
   INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 4', name_var);
END;


call sp_sample1();

SELECT * FROM results;
Copy
結果

COL1

COL2

SELECT 1

NAME 1

SELECT 2

NAME 2

SELECT 3

NAME 3

SELECT 4

NAME 4

Snowflake
CREATE OR REPLACE PROCEDURE sp_sample1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
   DECLARE
      -- Rowtype variable
      rowtype_variable OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - ROWTYPE DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();

      --Record variable
      !!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO OBJECT ***/!!!
      TYPE record_typ_def IS RECORD(ID number, NAME varchar2(23));
      record_variable_def OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - record_typ_def DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();

      -- Auxiliary variable
      name_var VARCHAR(20);
   BEGIN
      SELECT
         OBJECT_CONSTRUCT( *) INTO
         :rowtype_variable
      FROM
         sample_table
      WHERE ID = 1
      FETCH NEXT 1 ROWS ONLY;
      name_var := :rowtype_variable:NAME;
      INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 1', :name_var);

      SELECT
         OBJECT_CONSTRUCT()
      INTO
         :rowtype_variable
      FROM
         sample_table
      WHERE ID = 2
      FETCH NEXT 1 ROWS ONLY;
      name_var := :rowtype_variable:NAME;
      INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 2', :name_var);

      SELECT
         OBJECT_CONSTRUCT( *) INTO
         :record_variable_def
      FROM
         sample_table
      WHERE ID = 3
      FETCH NEXT 1 ROWS ONLY;
      name_var := :record_variable_def:NAME;
      INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 3', :name_var);

      SELECT
         OBJECT_CONSTRUCT('ID', ID, 'NAME', NAME) INTO
         :record_variable_def
      FROM
         sample_table
      WHERE ID = 4
      FETCH NEXT 1 ROWS ONLY;
      name_var := :record_variable_def:NAME;
      INSERT INTO RESULTS(COL1, COL2) VALUES('SELECT 4', :name_var);
   END;
$$;

call sp_sample1();

SELECT * FROM
   results;
Copy
結果

COL1

COL2

SELECT 1

NAME 1

SELECT 2

NAME 2

SELECT 3

NAME 3

SELECT 4

NAME 4

既知の問題

1.以下の機能は現在変換されていません。

  • 記録へのデータ取得。

  • ネストされた記録(記録の中の記録)。

  • 記録内のコレクション。

関連 EWIs

  1. SSC-EWI-0036: データ型が別のデータ型に変換されました。

  2. [SSC-EWI-0056](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0056):作成型はサポートされていません

  3. [SSC-FDM-0006](../../../general/technical-documentation/issues-and-troubleshooting/functional-difference/generalFDM.md#ssc-fdm-0006):数値型の列はSnowflakeでは同様の動作をしない場合があります。

  4. [SSC-FDM-OR0042](../../../general/technical-documentation/issues-and-troubleshooting/functional-difference/oracleFDM.md#ssc-fdm-or0042):日付型をタイムスタンプに変換すると異なる動作をします。

  5. SSC-FDM-OR0035: DBMS_OUTPUT.PUTLINE UDF 実装を確認します。

  6. [SSC-PRF-0003](../../../general/technical-documentation/issues-and-troubleshooting/performance-review/generalPRF.md#ssc-prf-0003):ループ内のフェッチは複雑なパターンとみなされるため、Snowflakeのパフォーマンスが低下する可能性があります。

配列型定義

これは、OracleのVarray宣言をSnowflakeに変換するための変換リファレンスです。

警告

このセクションは進行中であり、情報は将来変更される可能性があります。

注釈

このセクションは、Varrayの PL/SQL バージョンに関するものです。スタンドアロンバージョンについては、[配列型定義](../sql-translation-reference/create_type.md#array-type-definition)を参照してください。

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

varray(可変サイズ配列)は、要素数が0(空)から宣言された最大サイズまで変化する配列です。

varray変数の要素にアクセスするには、 variable_name(index) という構文を使います。インデックス の下限は1で、上限は現在の要素数です。要素の追加や削除によって上限は変わりますが、最大サイズを超えることはありません。データベースからvarrayを格納したり取り出したりするとき、そのインデックスと要素の順序は安定したままです。

(Oracle PL/SQL 言語リファレンス VARRAYS)

翻訳のために、型定義は ARRAY 半構造化データ型 に置き換えられ、その使用はあらゆる操作にわたって適宜変更されます。ネストされたテーブルとVarraysの翻訳が同じであることに注意してください。

varray型を定義するための構文は以下の通りです。

type_definition := { VARRAY | [VARYING] ARRAY } (size_limit) OF datatype
            [NOT NULL];

Copy

この型の変数を宣言するには

variable_name collection_type;

Copy

サンプルソースパターン

Varray定義

これは、3つの異なる方法でvarrayを作成する方法と、これらの変数の定義を移行する方法を示しています。

Oracle
CREATE OR REPLACE PROCEDURE associative_array_procedure
IS
    TYPE varray_typ IS ARRAY(10) OF INTEGER;
    TYPE varray_typ2 IS VARRAY(10) OF INTEGER;
    TYPE varray_typ3 IS VARYING ARRAY(10) OF INTEGER;

    array_variable varray_typ;
    array_variable2 varray_typ2;
    array_variable3 varray_typ3;
BEGIN
    NULL;
END;
Copy
Snowflake
CREATE OR REPLACE PROCEDURE associative_array_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
--        !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--        TYPE varray_typ IS ARRAY(10) OF INTEGER;
--        !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--        TYPE varray_typ2 IS VARRAY(10) OF INTEGER;
--        !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--        TYPE varray_typ3 IS VARYING ARRAY(10) OF INTEGER;

        array_variable VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'varray_typ' USAGE CHANGED TO VARIANT ***/!!!;
        array_variable2 VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'varray_typ2' USAGE CHANGED TO VARIANT ***/!!!;
        array_variable3 VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'varray_typ3' USAGE CHANGED TO VARIANT ***/!!!;
    BEGIN
        NULL;
    END;
$$;
Copy

Varrayの反復

Oracle
CREATE OR REPLACE PROCEDURE varray_iteration
IS
    TYPE varray_typ IS VARRAY(3) OF INTEGER;
    varray_variable varray_typ := varray_typ(10, 20, 30);
BEGIN
    FOR i IN 1..varray_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(varray_variable(i));
    END LOOP;
    
    varray_variable(1) := 40;
    
    FOR i IN 1..varray_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(varray_variable(i));
    END LOOP;
END;
/

CALL varray_iteration();
Copy
結果

DBMS に OUTPUT

10

20

30

40

20

30

Snowflake

注釈

要素の更新のための機能を実装するために UDF が追加されたことに注意してください。

この UDF は、後の改訂で追加される予定です。

CREATE OR REPLACE PROCEDURE varray_iteration ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
--        !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--        TYPE varray_typ IS VARRAY(3) OF INTEGER;
        varray_variable VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'varray_typ' USAGE CHANGED TO VARIANT ***/!!! := varray_typ(10, 20, 30);
    BEGIN
        --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
        FOR i IN 1 TO 0 /*varray_variable.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'VARRAY CUSTOM TYPE EXPRESSION' NODE ***/!!!
        --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
        LOOP
            --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
            CALL DBMS_OUTPUT.PUT_LINE_UDF(varray_variable(i));
        END LOOP;
            !!!RESOLVE EWI!!! /*** SSC-EWI-OR0108 - THE FOLLOWING ASSIGNMENT STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
            varray_variable(1) := 40;
            --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
            FOR i IN 1 TO 0 /*varray_variable.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'VARRAY CUSTOM TYPE EXPRESSION' NODE ***/!!!
            --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
               LOOP
            --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
            CALL DBMS_OUTPUT.PUT_LINE_UDF(varray_variable(i));
               END LOOP;
    END;
$$;

CALL varray_iteration();
Copy
UDF
CREATE OR REPLACE FUNCTION PUBLIC.INSERT_REPLACE_COLLECTION_ELEMENT_UDF(varray ARRAY, position INTEGER, newValue VARIANT)
RETURNS ARRAY
LANGUAGE SQL
AS
$$
    ARRAY_CAT(
        ARRAY_APPEND(ARRAY_SLICE(varray, 0, (position)-1), newValue),
        ARRAY_SLICE(varray, position, ARRAY_SIZE(varray)))
$$;
Copy
結果

DBMS に OUTPUT

10

20

30

40

20

30

既知の問題

1.現在、変換されていません

SnowConvert AI はこれらの要素の変換をサポートしていません。

2.インデックスの修正が必要です

Oracleのインデックスは1から始まりますが、Snowflakeでは0から始まります。

3.配列密度はオリジナルと一致しない場合があります

ARRAY データ型はまばらになる可能性があるため、配列の追加や削除を行う際には注意が必要です。密度が気になる場合は、このような操作の後に ARRAY_୧COMPACT()を使用すると便利です。

関連 EWIs

  1. [SSC-EWI-0058](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0058):機能は現在、Snowflakeスクリプトではサポートされていません。

  2. [SSC-EWI-0062](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0062):カスタム型の使用法がバリアントに変更されました。

  3. SSC-EWI-0073: 機能等価性レビュー保留中。

  4. [SSC-EWI-OR0108](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/oracleEWI.md#ssc-ewi-or0108):次の代入文は、Snowflakeスクリプトではサポートされていません。

  5. SSC-FDM-OR0035: DBMS_OUTPUT.PUTLINE UDF 実装を確認します。

コレクション一括操作

これは、Oracleコレクション一括操作をSnowflakeに変換するための変換リファレンスです。

警告

このセクションは進行中であり、情報は将来変更される可能性があります

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

一括 SQL の機能である BULK COLLECT 句は、 SQL から PL/SQL までの結果を、一度に1つではなくバッチで返します。

BULK COLLECT 句は、次の場合に出現します。

  • SELECT INTO ステートメント

  • FETCH ステートメント

  • 次の RETURNING INTO 句:

    • DELETE ステートメント

    • INSERT ステートメント

    • UPDATE ステートメント

    • EXECUTE IMMEDIATE ステートメント

BULK COLLECT 句を使用すると、前述の各ステートメントは、1回の操作で結果セット全体を取得し、1つまたは複数のコレクション変数に格納します(これは、ループステートメントを使用して一度に1つの結果行を取得するよりも効率的です)。

(Oracle PL/SQL 言語リファレンス BULK COLLECT CLAUSE)

このセクションでは、Bulk句を使用した SELECTs および FETCH カーソルの回避策をいくつか示します。

サンプルソースパターン

ソーステーブル

Oracle
CREATE TABLE bulk_collect_table(col1 INTEGER);

INSERT INTO bulk_collect_table VALUES(1);
INSERT INTO bulk_collect_table VALUES(2);
INSERT INTO bulk_collect_table VALUES(3);
INSERT INTO bulk_collect_table VALUES(4);
INSERT INTO bulk_collect_table VALUES(5);
INSERT INTO bulk_collect_table VALUES(6);
Copy
Snowflake
CREATE OR REPLACE TABLE bulk_collect_table (col1 INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

INSERT INTO bulk_collect_table
VALUES(1);

INSERT INTO bulk_collect_table
VALUES(2);

INSERT INTO bulk_collect_table
VALUES(3);

INSERT INTO bulk_collect_table
VALUES(4);

INSERT INTO bulk_collect_table
VALUES(5);

INSERT INTO bulk_collect_table
VALUES(6);
Copy

テーブルからのBulk Collect

Oracle
CREATE OR REPLACE PROCEDURE bulk_collect_procedure
IS
    CURSOR record_cursor IS
        SELECT *
        FROM bulk_collect_table;
        
    TYPE fetch_collection_typ IS TABLE OF record_cursor%ROWTYPE;
    fetch_collection_variable fetch_collection_typ;
    
    TYPE collection_typ IS TABLE OF bulk_collect_table%ROWTYPE;
    collection_variable collection_typ;
BEGIN
    SELECT * BULK COLLECT INTO collection_variable FROM bulk_collect_table;
    
    FOR i IN 1..collection_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(collection_variable(i).col1);
    END LOOP;
    
    collection_variable := null;
    OPEN record_cursor;
    FETCH record_cursor BULK COLLECT INTO collection_variable;
    CLOSE record_cursor;
    
    FOR i IN 1..collection_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(collection_variable(i).col1+6);
    END LOOP;
    
    collection_variable := null;
    EXECUTE IMMEDIATE 'SELECT * FROM bulk_collect_table' BULK COLLECT INTO collection_variable;
    
    FOR i IN 1..collection_variable.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE(collection_variable(i).col1+12);
    END LOOP;
END;
/

CALL bulk_collect_procedure();
Copy
結果

DBMS に OUTPUT

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Snowflake

危険

Bulk Collect句を使用した EXECUTE IMMEDIATE には回避策がありません。

注釈

なお、 FETCH カーソルはほぼそのまま使用できますが、パフォーマンスの問題から、可能な限り SELECT ステートメントに変更することをお勧めします。

CREATE OR REPLACE PROCEDURE bulk_collect_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        --** SSC-PRF-0009 - PERFORMANCE REVIEW - CURSOR USAGE **
        record_cursor CURSOR
        FOR
            SELECT *
            FROM
                bulk_collect_table;
--                !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--                TYPE fetch_collection_typ IS TABLE OF record_cursor%ROWTYPE;
    fetch_collection_variable VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'fetch_collection_typ' USAGE CHANGED TO VARIANT ***/!!!;
--                !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!

--    TYPE collection_typ IS TABLE OF bulk_collect_table%ROWTYPE;
    collection_variable VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'collection_typ' USAGE CHANGED TO VARIANT ***/!!!;
    BEGIN
                !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'RECORDS AND COLLECTIONS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
                SELECT * BULK COLLECT INTO collection_variable FROM bulk_collect_table;
                --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                FOR i IN 1 TO 0 /*collection_variable.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NESTED TABLE CUSTOM TYPE EXPRESSION' NODE ***/!!!
                --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                   LOOP
            --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
            CALL DBMS_OUTPUT.PUT_LINE_UDF(:collection_variable(i).col1);
                   END LOOP;
                !!!RESOLVE EWI!!! /*** SSC-EWI-OR0108 - THE FOLLOWING ASSIGNMENT STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!

                collection_variable := null;
                OPEN record_cursor;
                --** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
                record_cursor := (
            CALL FETCH_BULK_COLLECTION_RECORDS_UDF(:record_cursor)
                );
                collection_variable := :record_cursor:RESULT;
                CLOSE record_cursor;
                --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                FOR i IN 1 TO 0 /*collection_variable.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NESTED TABLE CUSTOM TYPE EXPRESSION' NODE ***/!!!
                --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                   LOOP
            --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
            CALL DBMS_OUTPUT.PUT_LINE_UDF(
            !!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '+' MAY NOT BEHAVE CORRECTLY BETWEEN unknown AND Number ***/!!!
            :collection_variable(i).col1+6);
                   END LOOP;
                !!!RESOLVE EWI!!! /*** SSC-EWI-OR0108 - THE FOLLOWING ASSIGNMENT STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!

                collection_variable := null;
                !!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
                EXECUTE IMMEDIATE 'SELECT * FROM
   bulk_collect_table'
                      !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'EXECUTE IMMEDIATE RETURNING CLAUSE' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
                      BULK COLLECT INTO collection_variable;
                --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                FOR i IN 1 TO 0 /*collection_variable.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NESTED TABLE CUSTOM TYPE EXPRESSION' NODE ***/!!!
                --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                   LOOP
            --** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
            CALL DBMS_OUTPUT.PUT_LINE_UDF(
            !!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '+' MAY NOT BEHAVE CORRECTLY BETWEEN unknown AND Number ***/!!!
            :collection_variable(i).col1+12);
                   END LOOP;
    END;
$$;

CALL bulk_collect_procedure();
Copy
結果

DBMS に OUTPUT

1

2

3

4

5

6

7

8

9

10

11

-- EXECUTE IMMEDIATE NOT EXECUTED、サポートされていません

SELECT INTO ステートメントケース

この場合、翻訳仕様は RESULTSETs を使用します。WITH、 SELECT、 BULK COLLECT INTO ステートメントのドキュメントはこちらをご覧ください。

with-select-and-bulk-collect-into-statements.md

既知の問題

1.FETCH カーソルの回避策における重いパフォーマンスの問題

Fetchカーソルの回避策は、仮テーブルのために重いパフォーマンスが要求されます。SELECT ステートメントに手動で移行することをお勧めします

2.Execute immediateステートメントは変換されません

これらは SnowConvert AI ではサポートされていませんが、手動で SELECT ステートメントに変更できます。

関連 EWIs

  1. [SSC-EWI-0058](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0058):機能は現在、Snowflakeスクリプトではサポートされていません。

  2. [SSC-EWI-0062](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0062):カスタム型の使用法がバリアントに変更されました。

  3. SSC-EWI-0073: 機能等価性レビュー保留中

  4. [SSC-EWI-OR0036](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/oracleEWI.md#ssc-ewi-or0036):型解決の問題で、文字列と日付の間の算術演算が正しく動作しないことがあります。

  5. [SSC-EWI-OR0108](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/oracleEWI.md#ssc-ewi-or0108):次の代入文は、Snowflakeスクリプトではサポートされていません。

  6. SSC-FDM-OR0035: DBMS_OUTPUT.PUTLINE UDF 実装を確認します。

  7. [SSC-PRF-0001](../../../general/technical-documentation/issues-and-troubleshooting/performance-review/generalPRF.md#ssc-prf-0001):このステートメントには、カーソルフェッチ一括操作の使用法があります。

  8. [SSC-EWI-0030](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0030):以下のステートメントには、動的 SQL を使用しています

WITH、 SELECT、および BULK COLLECT INTO ステートメント

危険

このセクションは翻訳仕様です。情報は将来変更される可能性があります。

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

このセクションは、 BULK COLLECT INTO ステートメントを使用する SELECT ステートメントに続く WITH ステートメントの翻訳仕様です。詳細情報については、以下のドキュメントをご覧ください。

サンプルソースパターン

注釈

わかりやすくするため、出力コードの一部を省略しています。

以下の例では、以下のクエリを使用しています。

Oracle

-- Sample MySampleTable table
CREATE TABLE MySampleTable (
  MySampleID NUMBER PRIMARY KEY,
  FirstName VARCHAR2(50),
  Salary NUMBER,
  Department VARCHAR2(50)
);

-- Insert some sample data
INSERT INTO MySampleTable (MySampleID, FirstName, Salary, Department)
VALUES (1, 'Bob One', 50000, 'HR');

INSERT INTO MySampleTable (MySampleID, FirstName, Salary, Department)
VALUES (2, 'Bob Two', 60000, 'HR');

INSERT INTO MySampleTable (MySampleID, FirstName, Salary, Department)
VALUES (3, 'Bob Three', 75000, 'IT');

INSERT INTO MySampleTable (MySampleID, FirstName, Salary, Department)
VALUES (4, 'Bob Four', 80000, 'IT');
Copy
Snowflake
-- Sample MySampleTable table
CREATE OR REPLACE TABLE MySampleTable (
   MySampleID NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/ PRIMARY KEY,
   FirstName VARCHAR(50),
   Salary NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
   Department VARCHAR(50)
 )
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

-- Insert some sample data
INSERT INTO MySampleTable(MySampleID, FirstName, Salary, Department)
VALUES (1, 'Bob One', 50000, 'HR');

INSERT INTO MySampleTable(MySampleID, FirstName, Salary, Department)
VALUES (2, 'Bob Two', 60000, 'HR');

INSERT INTO MySampleTable(MySampleID, FirstName, Salary, Department)
VALUES (3, 'Bob Three', 75000, 'IT');

INSERT INTO MySampleTable(MySampleID, FirstName, Salary, Department)
VALUES (4, 'Bob Four', 80000, 'IT');
Copy

1.プロシージャ内部の単純なケース

危険

これは結果セットデータ型を使用するアプローチです。ユーザー定義型の見直しが必要です。RESULTSETs の詳細情報については、以下の Snowflakeドキュメント を参照してください。

以下の例ではユーザー定義型を使用し、テーブルとして間接的に宣言しています。この場合の翻訳では、Snowflakeのデータ型として RESULTSET を実装します。結果セットは変数に格納され、 TABLE() 関数でラップして返す必要があります。

Oracle
CREATE OR REPLACE PROCEDURE simple_procedure
IS
  TYPE salary_collection IS TABLE OF NUMBER;
  v_salaries salary_collection := salary_collection();

BEGIN
  WITH IT_Employees AS (
    SELECT Salary
    FROM MySampleTable
    WHERE Department = 'IT'
  )
  SELECT Salary BULK COLLECT INTO v_salaries
  FROM IT_Employees;
END;

CALL simple_procedure();
Copy
結果

注釈

クエリは結果を返しませんが、予想される収集情報は、例で使用した IT 給与情報です。

IT_Salary

75000

80000

危険

RESULTSETs の制限の一つは、テーブルとして使えないことです。例: select * from my_result_set; (これはエラーです。詳細は以下の ドキュメント をご参照ください)。

Snowflake
CREATE OR REPLACE PROCEDURE simple_procedure ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
  // SnowConvert AI Helpers Code section is omitted.

  !!!RESOLVE EWI!!! /*** SSC-EWI-OR0072 - PROCEDURAL MEMBER TYPE DEFINITION NOT SUPPORTED. ***/!!!
  /*   TYPE salary_collection IS TABLE OF NUMBER */
  ;
  !!!RESOLVE EWI!!! /*** SSC-EWI-OR0104 - UNUSABLE VARIABLE, ITS TYPE WAS NOT TRANSFORMED ***/!!!
  /*   v_salaries salary_collection := salary_collection() */
  ;
  EXEC(`SELECT Salary
    FROM
       MySampleTable
    WHERE Department = 'IT'`);
  [
    !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'PlBulkCollectionItem' NODE ***/!!!
    //v_salaries
    null,V_SALARIES] = EXEC(`SELECT
   Salary
 FROM IT_Employees`);
$$;

CALL simple_procedure();
Copy
結果

SALARY

77500

80000

2.反復の単純なケース: FOR LOOP ステートメント

次のケースは、 FOR...LOOP との反復のための翻訳を定義することです。この場合、ユーザー定義型は暗黙のうちにテーブルであり、カーソルを使用して反復することが可能です。詳しくは以下のドキュメントをご覧ください。

Oracle
CREATE OR REPLACE PROCEDURE simple_procedure
IS
  TYPE salary_collection IS TABLE OF NUMBER;
  v_salaries salary_collection := salary_collection();
  v_average_salary NUMBER;
  salaries_count NUMBER;

BEGIN
  salaries_count := 0;
  WITH IT_Employees AS (
    SELECT Salary
    FROM MySampleTable
    WHERE Department = 'IT'
  )
  SELECT Salary BULK COLLECT INTO v_salaries
  FROM IT_Employees;

  -- Calculate the average salary
  IF v_salaries.COUNT > 0 THEN
    v_average_salary := 0;
    FOR i IN 1..v_salaries.COUNT LOOP
		v_average_salary := v_average_salary + v_salaries(i);
		salaries_count := salaries_count + 1;
    END LOOP;
    v_average_salary := v_average_salary / salaries_count;
  END IF;

  -- Display the average salary
  DBMS_OUTPUT.PUT_LINE('Average Salary for IT Department: ' || v_average_salary);
END;
/

CALL simple_procedure();
Copy
結果
Statement processed.
Average Salary for IT Department: 77500

Copy
Snowflake
CREATE OR REPLACE PROCEDURE simple_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
	DECLARE
--		!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--		TYPE salary_collection IS TABLE OF NUMBER;
		v_salaries VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'salary_collection' USAGE CHANGED TO VARIANT ***/!!! := salary_collection();
		v_average_salary NUMBER(38, 18);
		salaries_count NUMBER(38, 18);
	BEGIN
		salaries_count := 0;
		WITH IT_Employees AS
		(
		  SELECT Salary
		  FROM
		  	MySampleTable
		  WHERE Department = 'IT'
		)
		!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'RECORDS AND COLLECTIONS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
		SELECT Salary BULK COLLECT INTO v_salaries
		FROM IT_Employees;
		-- Calculate the average salary
		IF (null /*v_salaries.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NESTED TABLE CUSTOM TYPE EXPRESSION' NODE ***/!!! > 0) THEN
		  v_average_salary := 0;
		  --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
		  FOR i IN 1 TO 0 /*v_salaries.COUNT*/!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NESTED TABLE CUSTOM TYPE EXPRESSION' NODE ***/!!!
 		                                                                                                                                                                        --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
 		                                                                                                                                                                        LOOP
		  	v_average_salary :=
		  	!!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '+' MAY NOT BEHAVE CORRECTLY BETWEEN NUMBER AND salary_collection ***/!!!
		  	:v_average_salary + v_salaries(i);
		  	salaries_count := :salaries_count + 1;
 		                                                                                                                                                                           END LOOP;
		  v_average_salary := :v_average_salary / :salaries_count;
		END IF;
		-- Display the average salary
		--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
		CALL DBMS_OUTPUT.PUT_LINE_UDF('Average Salary for IT Department: ' || NVL(:v_average_salary :: STRING, ''));
	END;
$$;

CALL simple_procedure();
Copy
結果

SIMPLE_PROCEDURE

IT 部門の平均給与:77500

既知の問題

1.結果セットの制限。

RESULTSET データ型の使用には制限があります。詳しくは、以下の Snowflakeドキュメント をご覧ください。マーク可能な制限は以下の通りです。

  • 型 RESULTSET の列を宣言する。

  • 型 RESULTSET のパラメーターを宣言する。

  • ストアドプロシージャの戻り型を RESULTSET として宣言する。

2.Bulk Collect句を含む実行ステートメントはサポートされていません。

以下の ドキュメントを確認してください。

関連 EWIs

  1. [SSC-EWI-0058](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0058):機能は現在、Snowflakeスクリプトではサポートされていません。

  2. [SSC-EWI-0062](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI.md#ssc-ewi-0062):カスタム型の使用法がバリアントに変更されました。

  3. SSC-EWI-0073: 機能等価性レビュー保留中

  4. [SSC-EWI-OR0036](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/oracleEWI.md#ssc-ewi-or0036):型解決の問題で、文字列と日付の間の算術演算が正しく動作しないことがあります。

  5. [SSC-EWI-OR0072](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/oracleEWI.md#ssc-ewi-or0072):手続きメンバーはサポートされていません

  6. [SSC-EWI-OR0104](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/oracleEWI.md#ssc-ewi-or0104):使用できないコレクション変数です。

  7. [SSC-FDM-0006](../../../general/technical-documentation/issues-and-troubleshooting/functional-difference/generalFDM.md#ssc-fdm-0006):数値型の列はSnowflakeでは同様の動作をしない場合があります。

  8. SSC-FDM-OR0035: DBMS_OUTPUT.PUTLINE UDF 実装を確認します。