EXECUTE IMMEDIATE FROM

EXECUTE IMMEDIATE FROM は、ステージ内のファイルで指定された SQL ステートメントを実行します。ファイルには SQL ステートメントまたは Snowflakeスクリプトブロック を含めることができます。ステートメントは構文的に正しい SQL ステートメントにする必要があります。

EXECUTE IMMEDIATE FROM コマンドを使用すると、どのSnowflakeセッションからでもファイル内のステートメントを実行できます。

この機能は、Snowflakeオブジェクトとコードの展開と管理を制御するメカニズムを提供します。たとえば、ストアドスクリプトを実行して、すべてのアカウントに標準のSnowflake環境を作成することができます。構成スクリプトには、新しいアカウントごとにユーザー、ロール、データベース、スキーマを作成するステートメントが含まれる場合があります。

Jinja2テンプレート化

EXECUTE IMMEDIATE FROM は、Jinja2テンプレート化言語を使ってテンプレートファイルを実行することもできます。テンプレートには変数や式を含めることができ、ループや条件分岐、変数の置換、マクロなどを使用することができます。テンプレートには、他のテンプレートを含めることもでき、ステージングされた他のファイルで定義されたマクロをインポートすることもできます。

テンプレート化言語の詳細については、 Jinja2ドキュメント をご参照ください。

実行するファイルは以下の条件を満たす必要があります。

  • 構文的に有効なJinja2テンプレートであること。

  • ステージまたは Gitリポジトリのクローン にあります。

  • 構文的に有効な SQL ステートメントをレンダリングできること。

テンプレート化によって、より柔軟な制御構造と、環境変数を使用したパラメーター化を実現できます。たとえば、テンプレートを使用して、スクリプトで定義したオブジェクトの展開ターゲットを動的に選択することができます。SQL スクリプトをレンダリングするためにテンプレートを使用するには、 テンプレートディレクティブ を使用するか、少なくとも1つのテンプレート変数を持つ USING 句 を追加します。

テンプレート化ディレクティブ

2つのテンプレートディレクティブのいずれかを使うことができます。

推奨ディレクティブは SQL の有効な構文を使います。

--!jinja 
Copy

オプションで、代替ディレクティブを使うこともできます。

#!jinja 
Copy

注釈

ディレクティブの前には、バイトオーダーマークと最大10文字までの空白文字(改行、タブ、スペース)のみを配置することができます。ディレクティブの後に続く文字は無視されます。

ステージングされたファイルのコンテンツをテンプレートで使用する方法

テンプレートは SnowflakeFile API から直接、またはJinja2の includeimport、および inheritance 機能を使って他のステージングされたファイルをロードできます。

ファイルは絶対パスで参照できます。

{% include "@my_stage/path/to/my_template" %} {% import "@my_stage/path/to/my_template" as my_template %} {% extends "@my_stage/path/to/my_template" %} {{ SnowflakeFile.open("@my_stage/path/to/my_template", 'r', require_scoped_url = False).read() }} 
Copy

インクルード、インポート、エクステンドは相対パスもサポートし、 SnowflakeFile API はスコープされたSnowflakeファイル URLs をサポートします。

{% include "my_template" %} {% import "../my_template" as my_template %} {% extends "/path/to/my_template" %} 
Copy
こちらもご参照ください。

EXECUTE IMMEDIATE

構文

EXECUTE IMMEDIATE FROM { absoluteFilePath | relativeFilePath } [ USING ( <key> => <value> [ , <key> => <value> [ , ... ] ] ) ] [ DRY_RUN = { TRUE | FALSE } ] 
Copy

条件:

absoluteFilePath ::= @[ <namespace>. ]<stage_name>/<path>/<filename> 
Copy
relativeFilePath ::= '[ / | ./ | ../ ]<path>/<filename>' 
Copy

必須パラメーター

絶対ファイルパス(absoluteFilePath

namespace

内部ステージまたは外部ステージが存在するデータベースまたはスキーマ、あるいはその両方で、 database_name.schema_name または schema_name の形式です。データベースとスキーマがユーザーセッション内で現在使用されている場合、名前空間は オプション です。それ以外の場合は必須です。

stage_name

内部または外部ステージの名前。

path

ステージ内にある、大文字と小文字を区別したファイルへのパス。

filename

実行するファイルの名前。構文的に正しく、有効な SQL ステートメントが含まれている必要があります。各ステートメントはコンマで区切る必要があります。

相対ファイルパス(relativeFilePath

path

ステージ内にある、大文字と小文字を区別したファイルへの相対パス。相対パスは、先頭の / でステージのファイルシステムのルートを示し、 ./ で現在のディレクトリ(親ファイルがあるディレクトリ)を参照し、 ../ で親ディレクトリを参照するなど、確立された規則をサポートします。詳細については、 使用上の注意 をご参照ください。

filename

実行するファイルの名前。構文的に正しく、有効な SQL ステートメントが含まれている必要があります。各ステートメントはコンマで区切る必要があります。

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

USING ( <key> => <value> [ , <key> => <value> [ , ... ] ]  )

テンプレート展開のパラメーターとして使用できる、1つ以上のキーと値のペアを渡すことができます。キーと値のペアはコンマ区切りのリストを形成する必要があります。

USING 句がある場合、ファイルは SQL スクリプトとして実行される前に、まず Jinja2テンプレートとしてレンダリング されます。

条件:

  • key はテンプレート変数の名前です。テンプレート変数名は、オプションで二重引用符(")で囲むことができます。

  • value はテンプレートの変数に割り当てる値です。文字列値は ' または $$ で囲む必要があります。例については、 テンプレート化の使用上の注意 をご参照ください。

DRY_RUN = { TRUE | FALSE }

SQL スクリプトとして実行せずに、 レンダリングファイル をプレビューするかどうかを指定します。

  • TRUE は、 SQL ステートメントを実行せずに、レンダリングされたファイルのコンテンツを返します。

  • FALSE は、テンプレートから SQL ステートメントをレンダリングし、それらのステートメントを実行します。

デフォルト: FALSE

戻り値

EXECUTE IMMEDIATE FROM は次を返します。

  • すべてのステートメントが正常に実行された場合の、ファイルにある最後のステートメントの結果。

  • ファイル内のステートメントが失敗した場合のエラーメッセージ。

    ファイル内のステートメントにエラーがある場合、 EXECUTE IMMEDIATE FROM コマンドは失敗し、失敗したステートメントのエラーメッセージが返されます。

    注釈

    EXECUTE IMMEDIATE FROM コマンドが失敗してエラーメッセージを返した場合、ファイル内の失敗したステートメントより前のステートメントは正常に完了しています。

アクセス制御の要件

  • EXECUTE IMMEDIATE FROM コマンドの実行に使用される ロール には、ファイルがあるステージに対する USAGE (外部ステージ)または READ (内部ステージ)権限が必要です。

  • ファイルの実行に使用されるロールは、そのロールが権限を持つファイル内のステートメントのみを実行することができます。たとえば、ファイル内に CREATE TABLE ステートメントがある場合、ロールにはアカウントに テーブルを作成するための必要な権限 が求められます。必要な権限がないと、ステートメントは失敗します。

スキーマ内のオブジェクトに対して操作を実行するには、親データベースとスキーマに対する USAGE 権限が必要です。

指定された権限のセットを使用してカスタムロールを作成する手順については、 カスタムロールの作成 をご参照ください。

セキュリティ保護可能なオブジェクト に対して SQL アクションを実行するためのロールと権限付与に関する一般的な情報については、 アクセス制御の概要 をご参照ください。

使用上の注意

  • 実行されるファイルの SQL ステートメントには、 EXECUTE IMMEDIATE FROM ステートメントを含めることができます。

    • ネストされた EXECUTE IMMEDIATE FROM ステートメントでは、 相対ファイルパス使用できます

      相対パスは、親ファイルのステージとファイルパスを基準に評価されます。相対ファイルパスが / で始まる場合、パスは親ファイルを含むステージのルートディレクトリから始まります。

      例については、 をご参照ください。

    • 相対ファイルパスは、一重引用符(')または $$ で囲む必要があります。

    • ネストされたファイルの最大実行深度は5です。

  • 絶対ファイルパスは、オプションで一重引用符(')または $$ で囲むことができます。

  • 実行するファイルのサイズは 10MB を超過することはできません。

  • 実行するファイルは UTF-8 でエンコードする必要があります。

  • 実行するファイルは解凍されている必要があります。 PUT コマンドを使用して内部ステージにファイルをアップロードする場合は、 AUTO_COMPRESS パラメーター を明示的に FALSE に設定する必要があります。

    たとえば、 my_file.sqlmy_stage にアップロードします。

    PUT file://~/sql/scripts/my_file.sql @my_stage/scripts/ AUTO_COMPRESS=FALSE; 
    Copy
  • ディレクトリ内の全ファイルの実行はサポートされていません。例えば、 EXECUTE IMMEDIATE FROM @stage_name/scripts/ はエラーになります。

テンプレート化の使用上の注意

  • テンプレート内の変数名は大文字と小文字を区別します。

  • オプションで、テンプレート変数名を二重引用符で囲むことができます。 予約キーワード が変数名として使われている場合は、変数名を囲むと便利です。

  • USING 句では、以下のパラメーター型がサポートされています。

    • 文字列。 ' または $$ で囲む必要があります。例: USING (a => 'a', b => $$b$$)

    • 数値(10進数および整数)。例: USING (a => 1, b => -1.23)

    • ブール値。例: USING (a => TRUE, b => FALSE)

    • NULL。例: USING (a => NULL)

      注釈

      Jinja2テンプレート化エンジンは NULL の値をPython NoneType の型として解釈します。

    • セッション変数。例: USING (a => $var)。サポートされているデータ型の値を保持するセッション変数のみが許可されます。

    • バインド変数。例: USING (a => :var)。サポートされているデータ型の値を保持するバインド変数のみが許可されます。バインド変数を使用して、ストアドプロシージャの引数をテンプレートに渡すことができます。

  • Snowflake GitリポジトリやSnowflake Native Apps内のファイルには、テンプレートからアクセスできません。

  • 現在、テンプレートレンダリングの最大結果サイズは 100.000 バイトです。

  • テンプレートはJinja2バージョン3.1.4のテンプレート化エンジンを使ってレンダリングされます。

EXECUTE IMMEDIATE FROM エラーのトラブルシューティング

このセクションには、 EXECUTE IMMEDIATE FROM ステートメントに起因する一般的なエラーと、その解決方法が含まれています。

ファイルエラー

エラー

001501 (02000): File '<directory_name>' not found in stage '<stage_name>'. 

原因

このエラーには複数の原因があります。

  • ファイルが存在しない。

  • ファイル名がディレクトリのルートである。例: @stage_name/scripts/

解決策

ファイル名を確認し、ファイルが存在することを確認します。ディレクトリ内の全ファイルの実行はサポートされていません。

エラー

001503 (42601): Relative file references like '<filename.sql>' cannot be used in top-level EXECUTE IMMEDIATE calls. 

原因

ファイル実行の外部で、相対ファイルパスを使用してステートメントが実行された。

解決策

相対ファイルパスは、ファイル内の EXECUTE IMMEDIATE FROM ステートメントでのみ使用できます。ファイル用に ファイルの絶対パス を使用します。詳細については、 使用上の注意 をご参照ください。

エラー

001003 (42000): SQL compilation error: syntax error line <n> at position <m> unexpected '<string>'. 

原因

ファイルに SQL 構文エラーがある。

解決策

ファイルの構文エラーを修正し、ステージにファイルを再アップロードします。

ステージエラー

エラー

002003 (02000): SQL compilation error: Stage '<stage_name>' does not exist or not authorized. 

原因

ステージが存在しないか、ステージにアクセスできない。

解決策

  • ステージ名を確認し、ステージが存在することを確認します。

  • ステージへのアクセスに必要な権限を持つロールを使用してステートメントを実行します。詳細については、 アクセス制御の要件 をご参照ください。

アクセス制御エラー

エラー

003001 (42501): Uncaught exception of type 'STATEMENT_ERROR' in file <file_name> on line <n> at position <m>: SQL access control error: Insufficient privileges to operate on schema '<schema_name>' 

原因

ステートメントの実行に使用されたロールに、ファイル内のステートメントの一部またはすべてを実行するために必要な権限がない。

解決策

ファイル内のステートメントを実行するために適切な権限を持つロールを使用します。詳細については、 アクセス制御の要件 をご参照ください。

ステージエラー もご参照ください。

テンプレート化エラー

エラー

001003 (42000): SQL compilation error: syntax error line [n] at position [m] unexpected '{'. 

原因

このファイルにはテンプレート化構造体(例: {{ table_name }})が含まれていますが、テンプレート化エンジンを使ってレンダリングされていません。テンプレートがレンダリングされない場合、テンプレート内のテキスト行は SQL ステートメントとして実行されます。ファイル内のテンプレート化構造体は、 SQL 構文エラーになる可能性があります。

解決策

テンプレート化ディレクティブ を追加するか、 USING 句 を指定してステートメントを再実行し、少なくとも1つのテンプレート変数を指定します。

エラー

000005 (XX000): Python Interpreter Error: jinja2.exceptions.UndefinedError: '<key>' is undefined in template processing 

原因

テンプレートで使用される変数が USING 句で指定されていない場合は、エラーが発生します。

解決策

テンプレート内の変数の名前と数を確認し、 USING 句を更新して、すべてのテンプレート変数の値を含めます。

エラー

001510 (42601): Unable to use value of template variable '<key>' 

原因

変数 key の値はサポートされていない型です。

解決策

テンプレート変数の値にサポートされているパラメーター型が使用されていることを確認してください。詳細については、 テンプレート化の使用上の注意 をご参照ください。

エラー

001518 (42601): Size of expanded template exceeds limit of 100,000 bytes. 

原因

レンダリングされたテンプレートのサイズが現在の制限を超えています。

解決策

テンプレート化されたファイルを複数の小さなテンプレートに分割し、入れ子になったスクリプトにテンプレート変数を渡しながら、それらを順次実行する新しいスクリプトを追加します。

基本的な例

この例では、ステージ my_stage にあるファイル create-inventory.sql を実行します。

  1. 次のステートメントを使用して、 create-inventory.sql という名前のファイルを作成します。

    CREATE OR REPLACE TABLE my_inventory( sku VARCHAR, price NUMBER ); EXECUTE IMMEDIATE FROM './insert-inventory.sql'; SELECT sku, price FROM my_inventory ORDER BY price DESC; 
    Copy
  2. 次のステートメントを使用して、 insert-inventory.sql という名前のファイルを作成します。

    INSERT INTO my_inventory VALUES ('XYZ12345', 10.00), ('XYZ81974', 50.00), ('XYZ34985', 30.00), ('XYZ15324', 15.00); 
    Copy
  3. 内部ステージ my_stage を作成します。

    CREATE STAGE my_stage; 
    Copy
  4. PUT コマンドを使用して、両方のローカルファイルをステージにアップロードします。

    PUT file://~/sql/scripts/create-inventory.sql @my_stage/scripts/ AUTO_COMPRESS=FALSE; PUT file://~/sql/scripts/insert-inventory.sql @my_stage/scripts/ AUTO_COMPRESS=FALSE; 
    Copy
  5. my_stagecreate-inventory.sql スクリプトを実行します。

    EXECUTE IMMEDIATE FROM @my_stage/scripts/create-inventory.sql; 
    Copy

    戻り値:

    +----------+-------+ | SKU | PRICE | |----------+-------| | XYZ81974 | 50 | | XYZ34985 | 30 | | XYZ15324 | 15 | | XYZ12345 | 10 | +----------+-------+ 

簡単なテンプレート例

  1. 2つの変数とテンプレートディレクティブでテンプレートファイル setup.sql を作成します。

    --!jinja CREATE SCHEMA {{env}}; CREATE TABLE RAW (COL OBJECT) DATA_RETENTION_TIME_IN_DAYS = {{retention_time}}; 
    Copy
  2. ステージを作成する --- すでにファイルをアップロードできるステージがある場合は オプション です。

    たとえば、Snowflakeに内部ステージを作成します。

    CREATE STAGE my_stage; 
    Copy
  3. ファイルをステージにコピーします。

    たとえば、 PUT コマンドを使用して、ファイル setup.sql をローカル環境からステージ my_stage にアップロードします。

    PUT file://path/to/setup.sql @my_stage/scripts/ AUTO_COMPRESS=FALSE; 
    Copy
  4. ファイル setup.sql を実行します。

    EXECUTE IMMEDIATE FROM @my_stage/scripts/setup.sql USING (env=>'dev', retention_time=>0); 
    Copy

マクロ、条件、ループ、インポートを含むテンプレートの例

  1. マクロ定義を含むテンプレートファイルを作成します。

    たとえば、ローカル環境に macros.jinja というファイルを作成します。

    {%- macro get_environments(deployment_type) -%} {%- if deployment_type == 'prod' -%} {{ "prod1,prod2" }} {%- else -%} {{ "dev,qa,staging" }} {%- endif -%} {%- endmacro -%} 
    Copy
  2. テンプレートファイルを作成し、ファイルの先頭にテンプレートディレクティブ(--!jinja2)を追加します。

    テンプレートディレクティブの後に、 import ステートメントを追加して、前のステップで作成したファイルに定義されたマクロをインポートします。たとえば、ローカル環境に setup-env.sql というファイルを作成します。

    --!jinja2 {% from "macros.jinja" import get_environments %} {%- set environments = get_environments(DEPLOYMENT_TYPE).split(",") -%} {%- for environment in environments -%} CREATE DATABASE {{ environment }}_db; USE DATABASE {{ environment }}_db; CREATE TABLE {{ environment }}_orders ( id NUMBER, item VARCHAR, quantity NUMBER); CREATE TABLE {{ environment }}_customers ( id NUMBER, name VARCHAR); {% endfor %} 
    Copy
  3. ステージを作成する --- すでにファイルをアップロードできるステージがある場合は オプション です。

    たとえば、Snowflakeに内部ステージを作成します。

    CREATE STAGE my_stage; 
    Copy
  4. ファイルをステージにコピーします。

    たとえば、 setup-env.sqlmacros.jinja のファイルをステージ my_stage にアップロードするには、内部環境から PUT コマンドを使用します。

    PUT file://path/to/setup-env.sql @my_stage/scripts/ AUTO_COMPRESS=FALSE; PUT file://path/to/macros.jinja @my_stage/scripts/ AUTO_COMPRESS=FALSE; 
    Copy
  5. テンプレートによってレンダリングされた SQL ステートメントをプレビューして、Jinja2コードに問題がないか確認します。

    EXECUTE IMMEDIATE FROM @my_stage/scripts/setup-env.sql USING (DEPLOYMENT_TYPE => 'prod') DRY_RUN = TRUE; 
    Copy

    戻り値:

    +----------------------------------+ | rendered file contents | |----------------------------------| | --!jinja2 | | CREATE DATABASE prod1_db; | | USE DATABASE prod1_db; | | CREATE TABLE prod1_orders ( | | id NUMBER, | | item VARCHAR, | | quantity NUMBER); | | CREATE TABLE prod1_customers ( | | id NUMBER, | | name VARCHAR); | | CREATE DATABASE prod2_db; | | USE DATABASE prod2_db; | | CREATE TABLE prod2_orders ( | | id NUMBER, | | item VARCHAR, | | quantity NUMBER); | | CREATE TABLE prod2_customers ( | | id NUMBER, | | name VARCHAR); | | | +----------------------------------+ 
  6. ファイル setup-env.sql を実行します。

    EXECUTE IMMEDIATE FROM @my_stage/scripts/setup-env.sql USING (DEPLOYMENT_TYPE => 'prod'); 
    Copy