こんにちは、データアナリティクス事業本部@那覇オフィスの下地です。
Redshiftはストアドプロシージャをサポートしております(Amazon Redshift のストアドプロシージャの作成)。
使用してみると便利だと実感しましたのでFizzBuzzコードを実装しながら内容を確認します。
1. はじめに
FizzBuzz問題【フィズバズ問題】とは、入力された数値を以下のように変換して出力するコードです。
- 3の倍数: 「Fizz」と出力
- 5の倍数: 「Buzz」と出力
- 3と5の倍数: 「FizzBuzz」と出力
- それ以外: 数値をそのまま出力
上記を指定回数分実行し表示するための処理を、公式サイト(サポートされている PL/pgSQL ステートメント)を確認しそれぞれ該当するステートメントを記載します。
- 条件分岐: if
- 繰り返し処理: loop
- 結果の表示: RAISE
このステートメント内容について確認しFizzBuzzを実装します。
1.1 条件分岐: if
まず、条件分岐を行うためにIF 条件ステートメントを使用しますので構文を記述します。 私は業務でpythonを使用する機会が多く、構文の記述が似ているので少し安心です。
IF boolean-expression THEN
statements
[ ELSIF boolean-expression THEN
statements
[ ELSIF boolean-expression THEN
statements
...] ]
[ ELSE
statements ]
END IF;
1.2 繰り返し処理: loop
続いて、繰り返す処理にはloop ステートメントを使用します。
公式サイトにはいくつかの方法がありますがFOR loop (整数バリアント)
を使用しますので該当部分の構文を記述します。
[<<label>>]
FOR name IN [ REVERSE ] expression .. expression LOOP
statements
END LOOP [ label ];
..
FOR i IN 1..10 LOOP
-- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;
1.3 結果の表示: RAISE
RAISE ステートメントを使用してプロシージャ実行時のログを出力します。
RAISEにはLOG/INFO/NOTICE/WARNING/EXCEPTION
のレベルがあり、EXCEPTION
はエラーを発生させ現行のトランザクションをキャンセルします。
RAISE出力ログを確認するために、引数なしのプロシージャを作成し実行結果を表にまとめます。 ログの確認にはSVL_STORED_PROC_MESSAGESを使用します。
-- RAISE出力ログを確認するプロシージャコード
CREATE OR REPLACE PROCEDURE スキーマ.test_raise() AS $$
BEGIN
RAISE LOG '1: LOG';
RAISE INFO '2: INFO';
RAISE NOTICE '3: NOTICE';
RAISE WARNING '4: WARNING';
RAISE EXCEPTION '5: EXCEPTION test';
RAISE WARNING '6: WARNING';
END;
$$ LANGUAGE plpgsql;
-- 作成したプロシージャを実行
call スキーマ.test_raise();
-- 実行したログを確認
SELECT loglevel, loglevel_text, trim(message) as message
FROM svl_stored_proc_messages ORDER BY recordtime;
loglevel | loglevel_text | message |
---|---|---|
20 | LOG | 1: LOG |
30 | INFO | 2: INFO |
40 | NOTICE | 3: NOTICE |
50 | WARNING | 4: WARNING |
60 | EXCEPTION | 5: EXCEPTION test |
6: WARNING
までの1: LOG ~ 5: EXCEPTION test
が出力されており、EXCEPTIONで処理が中止されたことが確認できました。
2. FizzBuzzコードの作成
それでは確認したコードを使用してFizzBuzz用のコードを記載します。
2.1 コード部分
処理する回数は引数(cnt_value)として渡せるようにコードを作成します。
CREATE OR REPLACE PROCEDURE スキーマ.fizzbuzz_test(cnt_value int4) AS $$
DECLARE
n INTEGER := 1;
BEGIN
RAISE INFO 'めんそーれ';
FOR n IN 1..cnt_value LOOP
IF n % 3 = 0 AND n % 5 = 0 THEN
RAISE INFO 'n = FizzBuzz';
ELSEIF n % 3 = 0 THEN
RAISE INFO 'n = Fizz';
ELSEIF n % 5 = 0 THEN
RAISE INFO 'n = Buzz';
ELSE
RAISE INFO 'n = %', n;
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
2.2 実行と結果
それでは実際に動かして結果を確認します。
-- FizzBuzzコードを実行
call スキーマ.fizzbuzz_test(20);
-- 実行ログを確認
SELECT trim(message) as message
FROM svl_stored_proc_messages ORDER BY recordtime;
開始前にめんそーれ(ようこそ)
と出力されてますが、指定した20回分処理されていることが確認できました!
message |
---|
めんそーれ |
n = 1 |
n = 2 |
n = Fizz |
n = 4 |
n = Buzz |
n = Fizz |
n = 7 |
n = 8 |
n = Fizz |
n = Buzz |
n = 11 |
n = Fizz |
n = 13 |
n = 14 |
n = FizzBuzz |
n = 16 |
n = 17 |
n = Fizz |
n = 19 |
n = Buzz |
3. まとめ
条件/loop/RAISE
ステートメントの確認とFizzBuzzの実行確認まで行いました。
Redshiftストアドプロシージャはとても便利だなと実感しましたので、他のステートメントについても確認しもっと自在に操れるようになりたいなと思います。