ハンドラーコードのインラインまたはステージ上での保持¶
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";
}
}
$$;
CREATE PROCEDURE の参照情報については、 CREATE PROCEDURE をご参照ください。
ステージングされたハンドラーの使用¶
ステージングされたハンドラーを使用している場合は、 IMPORTS 句を使用して、ステージなどの別の場所でハンドラーを参照します。たとえば、 CREATE PROCEDURE や CREATE FUNCTION などの SQL ステートメントの IMPORTS 句を使用して、ハンドラーへのパスを指定します。
関数またはプロシージャから使用するためのハンドラーのステージング¶
次に、関数またはプロシージャが実行される環境にハンドラーファイルを追加する方法について説明します。
JavaやScalaで記述されたハンドラーなど、必要に応じて、ステージにアップロードするハンドラーコードをコンパイルおよびパッケージ化します。ビルドツールの詳細については、 ハンドラーコードのパッケージ化 をご参照ください。
Pythonで記述されたハンドラーの場合は、ハンドラーモジュールソースを使用できます。
コードで依存関係を利用できるようにする方法 の説明に従って、ハンドラーファイルをステージにアップロードします。
関数またはプロシージャを作成するときに、ハンドラーファイルを参照します。
依存関係の参照 で説明されているように、 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
句を使用して古いハンドラーファイルを上書きします。