■ はじめに
https://dk521123.hatenablog.com/entry/2022/12/09/152837
で、Snowflakeには、Timerみたいに疑似的な処理がなさそうで その代替え案としてストアドプロシージャを軽く触ったのを きっかけに調べてみた。
目次
【1】ストアドプロシージャ (Stored Procedure) 1)UDFs (ユーザー定義関数)との違い 【2】サポート言語 1)使用上の注意 【3】使い方 1)作成 - CREATE PROCEDURE - 2)実行(呼び出し) - CALL - 3)削除 - DROP PROCEDURE - 【4】コマンド 1)SHOW PROCEDURES 2)DESCRIBE PROCEDURE 【5】変数の扱い 1)変数の宣言 2)変数への値の格納
【1】ストアドプロシージャ (Stored Procedure)
https://docs.snowflake.com/ja/sql-reference/stored-procedures.html
より抜粋 ~~~~~~~~~ ストアドプロシージャでは、 プログラムによる構成を使用して、分岐とループを実行できます。 ~~~~~~~~~ => DBの PostgreSQL の ストアド に近い形で組むことができる
1)UDFs (ユーザー定義関数)との違い
に記載されているが、代表的なものとして以下。 ~~~~~ [1] ストアドプロシージャから値を返さなくていい(UDFは値を返す) [2] ストアドプロシージャは独立して呼び出し可能 ~~~~~
【2】サポート言語
https://docs.snowflake.com/ja/sql-reference/stored-procedures-overview.html
より抜粋 ~~~~~~~ 1)Java(Snowparkを使用) 2)JavaScript 3)Python(Snowparkを使用) 4)Scala(Snowparkを使用) 5)Snowflakeスクリプト ~~~~~~~ こんなにあるんだっと、びっくりした、、、
Snowflakeスクリプト
https://docs.snowflake.com/ja/sql-reference/stored-procedures-snowflake-scripting.html
1)使用上の注意
より抜粋 ~~~~~ 引数名は、ストアドプロシージャコードの SQL 部分では大文字と小文字を区別しませんが、 JavaScript部分では大文字と小文字を区別します。 ~~~~~
【3】使い方
1)作成 - CREATE PROCEDURE -
https://docs.snowflake.com/ja/sql-reference/sql/create-procedure.html
構文
CREATE PROCEDURE <関数名>(<引数>) RETURNS <戻り値 (テーブルも返せる)> LANGUAGE <言語(e.g. SQL) COMMENT = '<コメント文>' AS $$ -- ブロック (以下の「ブロックの基本構造」を参照) $$ ;
DECLARE -- https://docs.snowflake.com/ja/sql-reference/snowflake-scripting/declare.html ... (variable declarations, cursor declarations, etc.) ... BEGIN -- https://docs.snowflake.com/ja/sql-reference/snowflake-scripting/begin.html ... (Snowflake Scripting and SQL statements) ... EXCEPTION -- https://docs.snowflake.com/ja/sql-reference/snowflake-scripting/exception.html ... (statements for handling exceptions) ... END; -- EXCEPTION ブロック に関する詳細はl -- 以下の関連記事を参照のこと。
https://dk521123.hatenablog.com/entry/2022/12/23/223345
例
create or replace procedure say_hello(val1 varchar, val2 varchar) returns varchar not null language sql as $$ begin return :val1 || ' ' || :val2 || '!!'; end; $$ ;
2)実行(呼び出し) - CALL -
https://docs.snowflake.com/ja/sql-reference/sql/call.html
-- プロシージャを実行
CALL <ストアドプロシージャ名>(<引数>);
例
SET var1 = 'Hello'; SET var2 = 'World'; CALL say_hello($var1, $var2);
補足:即時実行について
* 以下の関連記事を参照のこと。
https://dk521123.hatenablog.com/entry/2022/12/17/000217
3)削除 - DROP PROCEDURE -
https://docs.snowflake.com/ja/sql-reference/sql/drop-procedure.html
例
drop procedure say_hello(varchar, varchar);
【4】コマンド
基本的に、他のコマンドと同じで、いつも通りなのだが、 SHOW PROCEDURESには、INがあったり、 DESCRIBE PROCEDUREには、()が入ったり ちょっこと異なる点もある。
1)SHOW PROCEDURES
https://docs.snowflake.com/ja/sql-reference/sql/show-procedures.html
-- アクセスする権限があるストアドプロシージャを一覧表示 SHOW PROCEDURES [ LIKE '<pattern>' ] [ IN ...];
2)DESCRIBE PROCEDURE
https://docs.snowflake.com/ja/sql-reference/sql/desc-procedure.html
-- ストアドプロシージャの署名(引数)、戻り値、言語、および本文(定義)などを表示 DESC[RIBE] PROCEDURE <procedure_name> ( [ <arg_data_type> [ , <arg_data_type_2> ... ] ] );
例
DESC PROCEDURE say_hello(); DESC PROCEDURE say_hello(varchar, varchar); -- 「DESC PROCEDURE say_hello;」だと、()がないので、エラー -- 引数が分からない場合は、まず「SHOW PROCEDURES;」 -- で調べるといいかも
【5】変数の扱い
* 以下の公式ドキュメントを一読するといい
https://docs.snowflake.com/ja/developer-guide/snowflake-scripting/variables.html
1)変数の宣言
* 以下の2通りで変わる a) DECLARE セクション内 b) BEGIN ... END セクション内
https://docs.snowflake.com/ja/developer-guide/snowflake-scripting/variables.html#declaring-a-variable
a) DECLARE セクション内
-- <variable_name> <type>; -- <variable_name> DEFAULT <expression> ; -- <variable_name> <type> DEFAULT <expression> ; declare profit number(38, 2) default 0.0;
b) BEGIN ... END セクション内
-- LET <variable_name> <type> { DEFAULT | := } <expression> ; -- LET <variable_name> { DEFAULT | := } <expression> ; begin let cost number(38, 2) := 100.0; let revenue number(38, 2) default 110.0;
2)変数への値の格納
a) 変数への値の割り当て
https://docs.snowflake.com/ja/developer-guide/snowflake-scripting/variables.html#assigning-a-value-to-a-declared-variable
-- <variable_name> := <expression> ; (「:=」で格納)
profit := revenue - cost;
b) SQL ステートメントでの変数の使用(バインド)
https://docs.snowflake.com/ja/developer-guide/snowflake-scripting/variables.html#using-a-variable-in-a-sql-statement-binding
-- 変数名の前にコロンを付ける insert into my_table (x) values (:my_variable) -- オブジェクトの名前として変数を使用している場合 -- (例: SELECT ステートメントの FROM 句にあるテーブルの名前)は、 -- IDENTIFIER キーワードを使用して、変数がオブジェクト識別子を表す select count(*) from identifier(:table_name)
関連記事
Snowflake ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/11/02/130111
Snowflake ~ 入門編 / Hello world ~
https://dk521123.hatenablog.com/entry/2021/11/22/212520
【Snowflake】ストアド ~ 基本編 / 条件分岐 ~
https://dk521123.hatenablog.com/entry/2022/12/26/211349
【Snowflake】ストアド ~ 基本編 / ループ ~
https://dk521123.hatenablog.com/entry/2022/12/16/143349
【Snowflake】ストアド ~ EXECUTE IMMEDIATE ~
https://dk521123.hatenablog.com/entry/2022/12/17/000217
【Snowflake】ストアド ~ クエリ結果を受け取る ~
https://dk521123.hatenablog.com/entry/2022/12/24/212242
【Snowflake】ストアド ~ 例外 / EXCEPTION ~
https://dk521123.hatenablog.com/entry/2022/12/23/223345
【Snowflake】ストアド ~ デバッグログについて ~
https://dk521123.hatenablog.com/entry/2022/12/18/121334
【Snowflake】ストアド ~ S3内にパーティション構成でUnloadする ~
https://dk521123.hatenablog.com/entry/2022/12/27/225629
【Snowflake】ストアド ~ ステージ内でデータ0件の場合エラーにする ~
https://dk521123.hatenablog.com/entry/2022/12/29/175848
Snowflake ~ テストデータ作成 / generator ~
https://dk521123.hatenablog.com/entry/2022/06/20/095659
ストアド ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2010/08/06/112528