ハンドラーコードのインラインまたはステージ上での保持¶
SQL を使用してユーザー定義の関数(UDF)またはストアドプロシージャを作成する場合、ステージ上のファイルなど、ハンドラーコードがそれを作成する SQL とインラインであるか、 SQL の外部であるかを指定できます。このトピックでは、違いについて説明します。
すべての言語がインラインまたはステージングハンドラーをサポートしているわけではありません。サポートされている言語のリストについては、 ストアドプロシージャの言語選択 または UDFs をご参照ください。
このトピックの内容:
実践的な違い¶
インラインハンドラーの利点¶
インラインハンドラーを持つ関数やプロシージャーは、管理しやすいかもしれません。開発ツールを使用してコードが正常に機能することを検証した後、実行する SQL ステートメントにコードをコピーして関数またはプロシージャを作成することでコードを展開できます。SQL ステートメント(ALTER FUNCTION や ALTER PROCEDURE など)を使用してコードを更新することで、他の場所でコードを維持する必要なく、そこでコードを維持できます。
ステージングされたハンドラーの利点¶
ステージングされたハンドラーを使用すると、次を実行できます。
- Snowflakeから使用しているGitリポジトリで個別に管理しているコードを使用します。 - 詳細については、 Snowflake がリモートの Git リポジトリと連携する仕組み をご参照ください。 
- 出力をすでにコンパイルしているがソースがない場合など、以前にコンパイルしたコードを使用できます。 
- 関数またはプロシージャを作成する 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";
      }
    }
  $$;
CREATE PROCEDURE の参照情報については、 CREATE PROCEDURE をご参照ください。
ステージングされたハンドラーの使用¶
ステージングされたハンドラーを使用している場合は、 IMPORTS 句を使用して、ステージなどの別の場所でハンドラーを参照します。たとえば、 CREATE PROCEDURE や CREATE FUNCTION などの SQL ステートメントの IMPORTS 句を使用して、ハンドラーへのパスを指定します。
ハンドラ関数名を HANDLER 句で参照する場合、その関数名を、それを含むクラス名またはモジュール名で修飾する必要があります。これはインラインハンドラーとは対照的で、ハンドラー関数の名前だけで参照できる場合もあります。
関数またはプロシージャから使用するためのハンドラーのステージング¶
次に、関数またはプロシージャが実行される環境にハンドラーファイルを追加する方法について説明します。
- JavaやScalaで記述されたハンドラーなど、必要に応じて、ステージにアップロードするハンドラーコードをコンパイルおよびパッケージ化します。ビルドツールの詳細については、 ハンドラーコードのパッケージ化 をご参照ください。 - Pythonで記述されたハンドラーの場合は、ハンドラーモジュールソースを使用できます。 - ハンドラーコードが Java または Scala で書かれている場合は、ストアドプロシージャに必要な依存関係をすべて含む JAR ファイルを作成します。後で、 JAR ファイルをステージにアップロードし、 CREATE PROCEDURE ステートメントから JAR ファイルをリファレンスする必要があります。アップロードしてリファレンスする JAR ファイルの数が少なければ、このプロセスはよりシンプルになります。 - Mavenを使用して、依存関係のある JAR ファイルをビルドする。 - Mavenを使用してコードをビルドおよびパッケージ化する場合は、 Mavenアセンブリプラグイン を使用して、すべての依存関係を含む JAR ファイルを作成できます。詳細については、 Mavenを使用したJavaまたはScalaハンドラーコードのパッケージ化 をご参照ください。 
- 他のツールを使用して、依存関係のある JAR ファイルをビルドする。 - Mavenを使用していない場合は、すべての依存関係を含む JAR ファイルをビルドする手順について、ビルドツールのドキュメントをご参照ください。 - たとえば、 IntelliJ IDEA プロジェクトを使用している場合は、 アーティファクト構成の設定に関する手順 をご参照ください。 
 
- コードで依存関係を利用できるようにする方法 の説明に従って、ハンドラーファイルをステージにアップロードします。 - ハンドラーが Snowflake で使用している Git リポジトリ からのものである場合、代わりにリモートのリポジトリからSnowflake Git リポジトリに 最新のものを取得する 必要があるかもしれません。 
- 関数またはプロシージャを作成するときに、ハンドラーファイルを参照します。 - 依存関係の参照 で説明されているように、 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' - CREATE FUNCTION の参照情報については、 CREATE FUNCTION をご参照ください。 
警告およびベストプラクティス¶
ハンドラーファイルを削除または名前変更すると、関数またはプロシージャを呼び出すことができなくなります。ハンドラーファイルを更新する必要がある場合は、次を実行します。
- 最初に、ハンドラーを使用する関数またはプロシージャが呼び出されていないことを確認します。 
- PUT コマンドを使用して、新しいハンドラーファイルをアップロードします。古いハンドラーファイルがまだ新しいファイルをアップロードするステージにある場合は、 - PUTコマンドの- OVERWRITE=TRUE句を使用して古いハンドラーファイルを上書きします。