ハンドラーコードのインラインまたはステージ上での保持

SQL を使用してユーザー定義の関数(UDF)またはストアドプロシージャを作成する場合、ステージ上のファイルなど、ハンドラーコードがそれを作成する SQL とインラインであるか、 SQL の外部であるかを指定できます。このトピックでは、違いについて説明します。

このトピックの内容:

実用的な違い

インラインハンドラーの利点

通常、実装は簡単です。開発ツールを使用してコードが正常に機能することを検証した後、実行する SQL ステートメントにコードをコピーして関数またはプロシージャを作成することでコードを展開できます。SQL ステートメント(ALTER FUNCTION や ALTER PROCEDURE など)を使用してコードを更新することで、他の場所でコードを維持する必要なく、そこでコードを維持できます。

ステージングされたハンドラーの利点

ステージングされたハンドラーを使用すると、次を実行できます。

  • 出力をすでにコンパイルしているがソースがない場合など、以前にコンパイルしたコードを使用できます。

  • 関数またはプロシージャを作成する SQL ステートメントに貼り付けるには大きすぎるハンドラーコードを使用できます。インラインコードには、ソースコードサイズの上限があります。

  • 複数の関数またはプロシージャからハンドラーコードを再利用できます。ステージングされたコードには、各関数を異なる UDF またはプロシージャで使用できる、複数のハンドラー関数を含めることができます。複数の UDFs またはプロシージャを作成すると、それぞれが同じハンドラーファイルを指定できますが、そのファイルに実装されている別のハンドラー関数を指定します。

    対照的に、インライン関数またはプロシージャのハンドラーには、通常、呼び出し可能な関数が1つだけ含まれます。その呼び出し可能な関数は他の関数を呼び出すことができ、それらの他の関数は同じコードファイルまたは別のステージングされたコードファイルで定義できます。

  • ほとんどの開発作業には、既存のテストおよびデバッグツールを使用する方が便利な場合があります。これは、コードが大きいか複雑な場合に特に当てはまります。

インラインハンドラーの使用

インラインハンドラーを使用している場合は、関数またはプロシージャを作成する SQL ステートメントの AS 句にハンドラーのソースコードを含めます。たとえば、 CREATE FUNCTION または CREATE PROCEDURE ステートメント自体の AS 句に、ハンドラーコードを含めます。

AS 句内では、コードを一重引用符または一対のドル記号($$)で囲みます。ソースコードに一重引用符が埋め込まれている場合などでは、二重ドル記号を使用する方が簡単な場合があります。

インラインハンドラーのソースコードをコンパイルする必要がある場合(JavaまたはScalaで記述されたハンドラーなど)、Snowflakeはソースをコンパイルし、後で使用するために出力(JAR ファイルなど)を保存します。オプションで、 TARGET_PATH 句を使用して、結果の出力ファイルの場所を指定できます。

Snowflakeは、コンパイルされた出力を次の方法で管理します。

  • SQL ステートメント(CREATE FUNCTION など)が TARGET_PATH を使用して出力ファイルの場所を指定する場合、Snowflakeはコードを一度コンパイルし、コンパイルされた出力を将来の使用のために保持します。

  • SQL ステートメントでファイルの場所が指定されていない場合、Snowflakeは関数またはプロシージャを呼び出す SQL ステートメントごとにコードを再コンパイルします。SQL ステートメントが終了すると、Snowflakeはファイルを自動的にクリーンアップします。

注釈

インラインJavaまたはScalaハンドラーを使用する際のベストプラクティスとして、 TARGET_PATH パラメーターに値を指定することを検討してください。これは、プロシージャまたは UDF を呼び出すたびにコードを再コンパイルする代わりに、Snowflakeがハンドラーコードのコンパイル結果を再利用するため、パフォーマンスを向上させることができます。

注意

ハンドラーコードがインラインで定義されている場合、それはメタデータとしてキャプチャされます。コードをメタデータとしてキャプチャしない場合は、 ステージングされたハンドラー を使用するなど、他の方法で展開することができます。

Snowflakeサービスを使用する場合、お客様は、個人データ(ユーザーオブジェクト向け以外)、機密データ、輸出管理データ、またはその他の規制されたデータがメタデータとして入力されていないことを確認する必要があります。詳細については、 Snowflakeのメタデータフィールド をご参照ください。

Javaハンドラーを使用したインラインの例

次の例のコードは、Javaのインラインハンドラーを使用して MYPROC ストアドプロシージャを作成します。ハンドラーは MyJavaClass クラスの run メソッドです。

CREATE OR REPLACE PROCEDURE MYPROC(fromTable STRING, toTable STRING, count INT)
  RETURNS STRING
  LANGUAGE JAVA
  RUNTIME_VERSION = '11'
  PACKAGES = ('com.snowflake:snowpark:latest')
  HANDLER = 'MyJavaClass.run'
  AS
  $$
    import com.snowflake.snowpark_java.*;

    public class MyJavaClass {
      public String run(Session session, String fromTable, String toTable, int count) {
        session.table(fromTable).limit(count).write().saveAsTable(toTable);
        return "SUCCESS";
      }
    }
  $$;
Copy

CREATE PROCEDURE の参照情報については、 CREATE PROCEDURE をご参照ください。

ステージングされたハンドラーの使用

ステージングされたハンドラーを使用している場合は、 IMPORTS 句を使用して、ステージなどの別の場所でハンドラーを参照します。たとえば、 CREATE PROCEDURE や CREATE FUNCTION などの SQL ステートメントの IMPORTS 句を使用して、ハンドラーへのパスを指定します。

関数またはプロシージャから使用するためのハンドラーのステージング

次に、関数またはプロシージャが実行される環境にハンドラーファイルを追加する方法について説明します。

  1. JavaやScalaで記述されたハンドラーなど、必要に応じて、ステージにアップロードするハンドラーコードをコンパイルおよびパッケージ化します。ビルドツールの詳細については、 ハンドラーコードのパッケージ化 をご参照ください。

    Pythonで記述されたハンドラーの場合は、ハンドラーモジュールソースを使用できます。

  2. コードで依存関係を利用できるようにする方法 の説明に従って、ハンドラーファイルをステージにアップロードします。

  3. 関数またはプロシージャを作成するときに、ハンドラーファイルを参照します。

    依存関係の参照 で説明されているように、 IMPORTS 句でハンドラーファイルを参照します。

    次の例のコードは、 my_udf という名前の UDF を作成します。そのハンドラー MyClass.myFunction はJavaで記述されています。コードの IMPORTS 句は、 my_handler.jar というハンドラーファイルが、ステージのサブディレクトリ handlers 内のステージ mystage にあることを指定します。実行時に、Snowflakeはハンドラー JAR をクラスパスに追加します。

    CREATE FUNCTION my_udf(i NUMBER)
      RETURNS NUMBER
      LANGUAGE JAVA
      IMPORTS = ('@mystage/handlers/my_handler.jar')
      HANDLER = 'MyClass.myFunction'
    
    Copy

    CREATE FUNCTION の参照情報については、 CREATE FUNCTION をご参照ください。

警告およびベストプラクティス

ハンドラーファイルを削除または名前変更すると、関数またはプロシージャを呼び出すことができなくなります。ハンドラーファイルを更新する必要がある場合は、次を実行します。

  • 最初に、ハンドラーを使用する関数またはプロシージャが呼び出されていないことを確認します。

  • PUT コマンドを使用して、新しいハンドラーファイルをアップロードします。古いハンドラーファイルがまだ新しいファイルをアップロードするステージにある場合は、 PUT コマンドの OVERWRITE=TRUE 句を使用して古いハンドラーファイルを上書きします。