❄
Snowflakeスクリプトの書き方
概要
Snowflakeスクリプトの基本的な書き方と実用例を説明します。
SQLは書けるけど、Snowflakeスクリプトは書いたことのない方向けの内容となります。
説明すること
- Snowflakeスクリプトの全体の構造
- DECLAREブロックとBEGINブロックの書き方
- カーソルの概要
- リザルトセットの概要
- FOR文(カーソルベース)の書き方
Snowflakeスクリプトとは
複数のSQL文を実行し、変数、条件分岐、ループなどのプログラミング的な処理を記述できる機能です。
SQLだけでは表現が難しい複雑なデータ処理やバッチ更新等を実施したいケースで有用です。
まずは全体像をつかむために、簡単な例を紹介します。
詳しい説明は後のセクションでおこないます。
サンプルコード
-- 売上データから条件に応じて処理する完全な例
DECLARE
total_sales NUMBER DEFAULT 0;
high_value_count NUMBER DEFAULT 0;
cur CURSOR FOR SELECT amount FROM sales WHERE sale_date = CURRENT_DATE();
BEGIN
FOR record IN cur DO
total_sales := total_sales + record.amount;
IF (record.amount > 1000) THEN
high_value_count := high_value_count + 1;
END IF;
END FOR;
RETURN '本日の売上合計: ' || total_sales || '円、高額取引: ' || high_value_count || '件';
END;
Snowflakeスクリプトの構造
スクリプトは大きく3つのブロックで構成されています。
- DECLAREブロック: 変数やカーソルを宣言(省略可能)
- BEGINブロック: メインの処理を記述(必須)
- EXCEPTIONブロック: エラー処理を記述(省略可能)
スクリプト構造
DECLARE
-- 変数やカーソルなどを宣言
BEGIN
-- メインとなる処理(SQLやスクリプト)を記載
EXCEPTION
-- 例外処理を記載
END;
DECLAREブロック
変数やカーソル、リザルトセット等を使用する場合は、このブロックで宣言します。
-
変数
変数を使用する前に、宣言をする必要があります。変数の宣言DECLARE update_stmt varchar(2000); --サンプル1 profit number(38, 2) DEFAULT 0.0; --サンプル2 BEGIN ...
-
カーソル
カーソルを使用することで、BEGINブロックのなかでクエリ結果を1行ずつ取り出して反復処理することができます。
宣言にはクエリが含まれます。カーソルの宣言DECLARE c1 CURSOR FOR SELECT price FROM invoices; --サンプル1 cur CURSOR FOR SELECT col1 from table1 where col2 is null; --サンプル2 BEGIN ...
-
リザルトセット
リザルトセット(RESULTSET)はクエリの結果セットを格納するデータ型です。
カーソルを使用することでリザルトセットを反復処理することができます。リザルトセットの宣言DECLARE res RESULTSET; --サンプル1 res RESULTSET DEFAULT (SELECT col1 FROM mytable ORDER BY col1); --サンプル2 BEGIN ...
BEGINブロック
BEGIN と END の間のブロックに、SQLやSnowflakeスクリプトを記述します。
BEGINブロックの例
BEGIN
CREATE TABLE table1 (id INTEGER, ...);
UPDATE table2 SET col1 = 'value1' WHERE col2 is not NULL;
END;
-
カーソル
カーソルはOPENコマンドを使用することで、クエリが実行され結果がカーソルに格納されます。
処理の完了後に、CLOSEコマンドを実行してカーソルを閉じます。カーソルの使用例DECLARE cur CURSOR FOR SELECT col1 from table1 where col2 is null; BEGIN OPEN cur; -- 処理を記述 CLOSE cur; END; -
リザルトセット
クエリをリザルトセットに割り当てることで実行することができます。
リザルトセットや変数の代入では、:=を使用します。リザルトセットの使用例DECLARE res RESULTSET; BEGIN res := (SELECT col1 FROM mytable ORDER BY col1); END;動的なSQL文字列を作成し実行する場合は、EXECUTE IMMEDIATEオプションを使用します。
リザルトセット(EXECUTE IMMEDIATE)の使用例DECLARE res RESULTSET; col_name varchar(100); update_statement varchar(1000); BEGIN col_name := 'col1'; update_statement := 'update table1 set ' || col_name || ' = 1'; res := (EXECUTE IMMEDIATE :update_statement); END; -
FORループ
FORループの回数は、ユーザーが直接指定するか、カーソルの行数で指定することができます。FORループ(回数指定)の使用例DECLARE sum INTEGER DEFAULT 0; maximum_count INTEGER default 10; BEGIN FOR i IN 1 TO maximum_count DO sum := sum + i; END FOR; RETURN sum; END;FORループ(カーソルベース)の使用例DECLARE update_stmt varchar(2000); res RESULTSET; cur CURSOR FOR SELECT col1 from table1 where col2 is null; BEGIN OPEN cur; FOR each_row IN cur DO update_stmt := 'update table1 set col1 = 1 ' || 'where col2 = ' || each_row.col1 || ';' res := (EXECUTE IMMEDIATE :update_stmt); END FOR; CLOSE cur; END;
おわりに
今回はSnowflakeスクリプトの書き方を紹介しました。
ストアドプロシージャやユーザ定義関数のなかで、SQLだけでは処理が困難なケースで利用する機会が多いのかなと感じました。
今回は基本的な書き方を整理しましたが、例外処理等の紹介を省略した内容についても今後理解していきたいと思います。
最後までお読みいただきありがとうございました。
Discussion