CALL (匿名プロシージャの場合)

ストアドプロシージャ に似ていますが、後で使用するために保存されない匿名プロシージャを作成して呼び出します。

このコマンドでは、WITH 句のパラメーターで定義された匿名プロシージャを作成し、そのプロシージャを呼び出します。

このコマンドには、CREATE PROCEDURE スキーマ権限を持つロールは必要ありません。

プロシージャは 呼び出し元の権限 で実行されます。つまり、プロシージャは、呼び出し元の権限で実行され、現在のセッションコンテキストを使用し、呼び出し元のセッション変数とパラメーターにアクセスできます。

こちらもご参照ください。

CREATE PROCEDURECALL

構文

JavaおよびScala

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE { SCALA | JAVA }
  RUNTIME_VERSION = '<scala_or_java_runtime_version>'
  PACKAGES = ( 'com.snowflake:snowpark:<version>' [, '<package_name_and_version>' ...] )
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<fully_qualified_method_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ AS '<procedure_definition>' ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

ステージングされたハンドラー を使用するJavaおよびScalaプロシージャの場合は、次の構文を使用します。

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE { SCALA | JAVA }
  RUNTIME_VERSION = '<scala_or_java_runtime_version>'
  PACKAGES = ( 'com.snowflake:snowpark:<version>' [, '<package_name_and_version>' ...] )
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<fully_qualified_method_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

JavaScript

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS <result_data_type> [ [ NOT ] NULL ]
  LANGUAGE JAVASCRIPT
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  AS '<procedure_definition>'
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

Python

インラインプロシージャの場合は、次の構文を使用します。

WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE PYTHON
  RUNTIME_VERSION = '<python_version>'
  PACKAGES = ( 'snowflake-snowpark-python[==<version>]'[, '<package_name>[==<version>]' ... ])
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<function_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
  AS '<procedure_definition>'
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

コードがステージ上のファイルにあるプロシージャの場合は、次の構文を使用します。

WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE PYTHON
  RUNTIME_VERSION = '<python_version>'
  PACKAGES = ( 'snowflake-snowpark-python[==<version>]'[, '<package_name>[==<version>]' ... ])
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<module_file_name>.<function_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

Snowflakeスクリプト

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS { <result_data_type> | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE SQL
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  AS '<procedure_definition>'
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

必須パラメーター

すべての言語

WITH name AS PROCEDURE ( [ arg_name arg_data_type ] [ , ... ] )

プロシージャの識別子(name)と入力引数を指定します。

  • 識別子用:

    • 識別子はアルファベットで始まる必要があり、識別子の文字列全体が二重引用符で囲まれている場合を除き、スペースや特殊文字を含めることはできません(例:"私のオブジェクト")。二重引用符で囲まれた識別子も大文字と小文字が区別されます。 識別子の要件 をご参照ください。

  • 入力引数の場合、

RETURNS result_data_type [ [ NOT ] NULL ]

プロシージャによって返される結果の型を指定します。

NOT NULL を使用して、プロシージャはnull以外の値のみを返す必要があることを指定します。デフォルトは NULL です。これは、プロシージャが NULL を返すことができることを意味します。

  • result_data_type には、使用している言語の型に対応するSnowflakeデータ型を使用します。

    注釈

    JavaまたはScalaで記述するプロシージャには、戻り値が必要です。Pythonでは、プロシージャが値を返さない場合は None を返していると見なされます。

    ハンドラー言語にかかわらず、このコマンドの WITH 句には、プロシージャが明示的に何も返さない場合でも、戻り型を定義する RETURNS 句を含める必要があることに注意してください。

  • 返されたテーブルの列の Snowflakeデータ型 がわかっている場合、 RETURNS TABLE ( [ col_name col_data_type [ , ... ] ] ) には、列名と型を指定します。

    WITH get_top_sales() AS PROCEDURE
      RETURNS TABLE (sales_date DATE, quantity NUMBER)
      ...
    CALL get_top_sales();
    
    Copy

    それ以外の場合(実行時に列タイプを決定する場合など)は、列名と型を省略できます。

    WITH get_top_sales() AS PROCEDURE
      ...
      RETURNS TABLE ()
    CALL get_top_sales();
    
    Copy

    注釈

    現在、 RETURNS TABLE(...) 句では、列型として GEOGRAPHY を指定できません。これは、ストアドプロシージャと匿名プロシージャのいずれを作成する場合にも適用されます。

    CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
      RETURNS TABLE(g GEOGRAPHY)
      ...
    
    Copy
    WITH test_return_geography_table_1() AS PROCEDURE
      RETURNS TABLE(g GEOGRAPHY)
      ...
    CALL test_return_geography_table_1();
    
    Copy

    列タイプとして GEOGRAPHY を指定しようとすると、ストアドプロシージャの呼び出しはエラーになります。

    Stored procedure execution error: data type of returned table does not match expected returned table type
    
    Copy

    これを回避するには、 RETURNS TABLE() の列の引数と型を省略できます。

    CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
      RETURNS TABLE()
      ...
    
    Copy
    WITH test_return_geography_table_1() AS PROCEDURE
      RETURNS TABLE()
      ...
    CALL test_return_geography_table_1();
    
    Copy

    RETURNS TABLE(...) は、ハンドラーが次の言語で記述されている場合にのみサポートされます。

実際問題として、 Snowflakeスクリプトのブロック 外では、 呼び出しは式の一部とすることはできないため、戻り値は使用できません

LANGUAGE language

プロシージャのハンドラーコードの言語を指定します。

現在、 language でサポートされている値は次のとおりです。

AS procedure_definition

プロシージャによって実行されるコードを定義します。定義は、任意の有効なコードで構成できます。

次の点に注意してください。

  • コードがインラインではないプロシージャの場合は、 AS 句を省略します。これには、 ハンドラーがステージにある プロシージャが含まれます。

    代わりに IMPORTS 句を使用して、プロシージャのコードを含むファイルの場所を指定します。詳細については、以下をご参照ください。

  • Snowflakeスクリプト内であっても、 procedure definition の前後には 文字列リテラル区切り文字' または $$)を使用する必要があります。

  • JavaScript のプロシージャで、改行を含む文字列を記述している場合は、文字列の前後にバッククォート(別称「バックティック」)を使用できます。

    次の JavaScript プロシージャの例では、プロシージャの本文に一重引用符と二重引用符が含まれているため、 $$ とバッククォートを使用しています。

    WITH proc3 AS PROCEDURE ()
      RETURNS VARCHAR
      LANGUAGE javascript
      AS
      $$
      var rs = snowflake.execute( { sqlText:
          `INSERT INTO table1 ("column 1")
              SELECT 'value 1' AS "column 1" ;`
          } );
      return 'Done.';
      $$
    CALL proc3();
    
    Copy
  • Snowflakeはハンドラーコードを検証しません。ただし、ハンドラーコードが無効な場合にコマンドを実行すると、エラーが発生します。

ストアドプロシージャの詳細については、 ストアドプロシージャの使用 をご参照ください。

CALL name ( [ [ arg_name => ] arg , ... ] )

プロシージャが呼び出すための識別子(name)と入力引数を指定します。

名前(arg_name => arg)または位置(arg)のいずれかで入力引数を指定します。

次の点に注意してください。

  • すべての引数を名前または位置のいずれかで指定する必要があります。一部の引数を名前で、他の引数を位置で指定することはできません。

    引数を名前で指定する場合は、引数名を二重引用符で囲むことはできません。

  • 2つの関数または2つのプロシージャが同じ名前で引数の型が異なり、引数名が異なる場合は、引数名を使ってどの関数またはプロシージャを実行するかを指定することができます。 プロシージャおよび関数のオーバーロード をご参照ください。

Java、Python、またはScala

RUNTIME_VERSION = 'language_runtime_version'

使用する言語ランタイムバージョン。サポートされているバージョンは次のとおりです。

  • Java: 11

  • Python:

    • 3.8

    • 3.9

    • 3.10

  • Scala: 2.12

PACKAGES = ( 'snowpark_package_name' [, 'package_name' ...] )

ハンドラーコードの実行環境に含める必要があるSnowflakeに展開された、パッケージの名前のコンマ区切りリスト。Snowparkパッケージはプロシージャに必要なため、常に PACKAGES 句で参照する必要があります。Snowparkの詳細については、 Snowpark API をご参照ください。

Snowflakeがプロシージャを実行する環境には、サポートされている言語用に選択されたパッケージのセットがデフォルトで含まれています。PACKAGES 句でこれらのパッケージを参照する場合、パッケージはSnowflakeですでに利用可能であるため、 IMPORTS 句でパッケージを含むファイルを参照する必要はありません。

指定の言語用にサポートされているパッケージとバージョンのリストについては、 INFORMATION_SCHEMA.PACKAGES ビュー でその言語をクエリして指定します。例:

SELECT * FROM information_schema.packages WHERE language = '<language>';
Copy

ここで、 languagejavapython、または scala です。

PACKAGES 句でパッケージを参照するための構文は、以下で説明するように、パッケージの言語によって異なります。

  • Java

    次の形式を使用して、パッケージ名とバージョン番号を指定します。

    domain:package_name:version
    
    Copy

    最新バージョンを指定するには、 latest に対して version を指定します。

    たとえば、Snowflakeにある最新のSnowparkライブラリのパッケージを含めるには、次を使用します。

    PACKAGES = ('com.snowflake:snowpark:latest')
    
    Copy

    Snowparkライブラリからのパッケージを指定する場合は、バージョン1.3.0以降を指定する必要があります。

  • Python

    Snowflakeには、Anacondaから入手できる多数のパッケージが含まれています。詳細については、 サードパーティパッケージの使用 をご参照ください。

    次の形式を使用して、パッケージ名とバージョン番号を指定します。

    package_name[==version]
    
    Copy

    最新バージョンを指定する場合は、バージョン番号を省略します。

    たとえば、spacyパッケージバージョン2.3.5を(必要なSnowparkパッケージの最新バージョンとともに)含めるには、次を使用します。

    PACKAGES = ('snowflake-snowpark-python', 'spacy==2.3.5')
    
    Copy

    Snowparkライブラリからのパッケージを指定する場合は、バージョン0.4.0以降を指定する必要があります。Snowflakeで利用可能な最新バージョンを使用するには、バージョン番号を省略します。

  • Scala

    次の形式を使用して、パッケージ名とバージョン番号を指定します。

    domain:package_name:version
    
    Copy

    最新バージョンを指定するには、 latest に対して version を指定します。

    たとえば、Snowflakeにある最新のSnowparkライブラリのパッケージを含めるには、次を使用します。

    PACKAGES = ('com.snowflake:snowpark:latest')
    
    Copy

    Snowflakeは、ScalaプロシージャでのSnowparkバージョン0.9.0以降の使用をサポートしています。ただし、これらのバージョンには制限があることに注意してください。たとえば、1.1.0より前のバージョンは、プロシージャでのトランザクションの使用をサポートしていません。

HANDLER = 'fully_qualified_method_name'
  • Python

    プロシージャの関数またはメソッドの名前を使用します。これは、コードがインラインであるか、ステージで参照されているかによって異なります。

    • コードがインラインの場合、次の例のように、関数名だけを指定できます。

      WITH myproc AS PROCEDURE()
        ...
        HANDLER = 'run'
        AS
        $$
        def run(session):
          ...
        $$
      CALL myproc();
      
      Copy
    • コードをステージからインポートする場合は、完全修飾ハンドラー関数名を <モジュール名>.<関数名> として指定します。

      WITH myproc AS PROCEDURE()
        ...
        IMPORTS = ('@mystage/my_py_file.py')
        HANDLER = 'my_py_file.run'
      CALL myproc();
      
      Copy
  • JavaおよびScala

    プロシージャのメソッドまたは関数の完全修飾名を使用します。これは通常、次の形式です。

    com.my_company.my_package.MyClass.myMethod
    
    Copy

    条件:

    com.my_company.my_package
    
    Copy

    オブジェクトまたはクラスを含むパッケージに対応します。

    package com.my_company.my_package;
    
    Copy

オプションのパラメーター

すべての言語

CALLED ON NULL INPUT または . RETURNS NULL ON NULL INPUT | STRICT

null入力で呼び出されたときのプロシージャの動作を指定します。入力がnullの場合は常にnullを返すシステム定義関数とは対照的に、プロシージャはnull入力を処理でき、入力がnullの場合でもnull以外の値を返します。

  • CALLED ON NULL INPUT は、null入力で常にプロシージャを呼び出します。そのような値を適切に処理するのは手順次第です。

  • RETURNS NULL ON NULL INPUT (またはその同義語 STRICT)は、入力がnullの場合にプロシージャを呼び出さないため、プロシージャ内のステートメントは実行されません。代わりに、null値が常に返されます。プロシージャは、null以外の入力に対してもnullを返す場合があります。

デフォルト: CALLED ON NULL INPUT

INTO :snowflake_scripting_variable

指定された Snowflakeスクリプト変数 をストアドプロシージャの戻り値に設定します。

Java、Python、またはScala

IMPORTS = ( 'stage_path_and_file_name_to_read' [, 'stage_path_and_file_name_to_read' ...] )

インポートするファイルの場所(ステージ)、パス、および名前。プロシージャが依存するファイルを含めるには、 IMPORTS 句を設定する必要があります。

  • インラインプロシージャを作成している場合は、コードがプロシージャまたはリソースファイルの外部で定義されたクラスに依存している場合を除き、この句を省略できます。

  • JavaまたはScala: ハンドラーがコードをコンパイルするプロシージャを記述する場合は、プロシージャのハンドラーを含む JAR ファイルへのパスも含める必要があります。

  • Python: プロシージャのコードがステージ上にある場合は、コードが含まれているモジュールファイルへのパスも含める必要があります。

IMPORTS 句の各ファイルは、ファイルが異なるサブディレクトリまたは異なるステージにある場合でも、一意の名前を持っている必要があります。

使用上の注意

一般的な使用法

  • プロシージャはアトミックではありません。プロシージャ内の1つのステートメントが失敗した場合、プロシージャ内の他のステートメントは必ずしもロールバックされるとは限りません。ストアドプロシージャとトランザクションについては、 トランザクション管理 をご参照ください。

  • プロシージャは、文字列(例: 成功/失敗インジケーター)や数値(例: エラーコード)などの単一の値のみを返すことができます。より広範な情報を返す必要がある場合は、区切り文字(コンマなど)で区切られた値を含む VARCHAR、または VARIANT などの半構造化データ型を返すことができます。

  • メタデータについて、

    注意

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

構文

  • WITH 句が SELECT ステートメントで使用される場合と同様に、 CALL ステートメントで使用される WITH 句は、プロシージャ定義に加えて、コンマで区切られた複数の CTEs の指定をサポートします。ただし、 WITH 句によって生成された表形式の値を CALL 句に渡すことはできません。

    ただし、 WITH 句で値が代入される単純な変数を指定することは可能です。

  • CALL 句は、構文の最後にする必要があります。

権限

  • このコマンドでプロシージャを作成して呼び出すには、CREATE PROCEDURE スキーマ権限を持つロールは必要ありません。

  • プロシージャのハンドラーコードは、このコマンドを実行したユーザーに割り当てられたロールに許可されたアクションのみを実行できます。

言語固有

  • Javaプロシージャについては、 既知の制限 をご参照ください。

  • Pythonプロシージャについては、 既知の制限 をご参照ください。

  • Scalaプロシージャについては、 既知の制限 をご参照ください。

次の例では、引数を位置で指定してプロシージャを作成し、呼び出します。

WITH copy_to_table AS PROCEDURE (fromTable STRING, toTable STRING, count INT)
  RETURNS STRING
  LANGUAGE SCALA
  RUNTIME_VERSION = '2.12'
  PACKAGES = ('com.snowflake:snowpark:latest')
  HANDLER = 'DataCopy.copyBetweenTables'
  AS
  $$
    object DataCopy
    {
      def copyBetweenTables(session: com.snowflake.snowpark.Session, fromTable: String, toTable: String, count: Int): String =
      {
        session.table(fromTable).limit(count).write.saveAsTable(toTable)
        return "Success"
      }
    }
  $$
  CALL copy_to_table('table_a', 'table_b', 5);
Copy

次の例では、引数を名前で指定してプロシージャを作成し、呼び出します。

WITH copy_to_table AS PROCEDURE (fromTable STRING, toTable STRING, count INT)
  RETURNS STRING
  LANGUAGE SCALA
  RUNTIME_VERSION = '2.12'
  PACKAGES = ('com.snowflake:snowpark:latest')
  HANDLER = 'DataCopy.copyBetweenTables'
  AS
  $$
    object DataCopy
    {
      def copyBetweenTables(session: com.snowflake.snowpark.Session, fromTable: String, toTable: String, count: Int): String =
      {
        session.table(fromTable).limit(count).write.saveAsTable(toTable)
        return "Success"
      }
      }
    }
  $$
  CALL copy_to_table(
    toTable => 'table_b',
    count => 5,
    fromTable => 'table_a');
Copy

その他の例については、以下のトピックをご参照ください。

プロシージャの例については、 ストアドプロシージャの使用 をご参照ください。