ハンドラーコードのインラインまたはステージ上での保持¶
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 リポジトリステージに取得する必要があるかもしれません。
関数またはプロシージャを作成するときに、ハンドラーファイルを参照します。
依存関係の参照 で説明されているように、 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
句を使用して古いハンドラーファイルを上書きします。