Redshiftストアドプロシージャを使用してFizzBuzzを実装してみる

2023.03.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、データアナリティクス事業本部@那覇オフィスの下地です。

Redshiftはストアドプロシージャをサポートしております(Amazon Redshift のストアドプロシージャの作成)。

使用してみると便利だと実感しましたのでFizzBuzzコードを実装しながら内容を確認します。

1. はじめに

FizzBuzz問題【フィズバズ問題】とは、入力された数値を以下のように変換して出力するコードです。

  • 3の倍数: 「Fizz」と出力
  • 5の倍数: 「Buzz」と出力
  • 3と5の倍数: 「FizzBuzz」と出力
  • それ以外: 数値をそのまま出力

上記を指定回数分実行し表示するための処理を、公式サイト(サポートされている PL/pgSQL ステートメント)を確認しそれぞれ該当するステートメントを記載します。

  1. 条件分岐: if
  2. 繰り返し処理: loop
  3. 結果の表示: 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ストアドプロシージャはとても便利だなと実感しましたので、他のステートメントについても確認しもっと自在に操れるようになりたいなと思います。

4. 参考リンク