2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PostgreSQLでストアードプロシージャでパラメーターをチェックする

Last updated at Posted at 2022-08-16

目的

ストアードプロシージャを使っていると入力パラメーターのチェックがしたくなります。

プログラム

CREATE OR REPLACE FUNCTION uv_set_test (
  p_uuid UUID DEFAULT NULL
  ,p_start_at TIMESTAMPTZ DEFAULT NULL
  ,p_content TEXT DEFAULT NULL
) RETURNS VOID AS $FUNCTION$
DECLARE
BEGIN
  -- パラメーターチェック
  IF NOT (
    p_uuid IS NOT NULL
    AND p_start_at IS NOT NULL AND p_start_at >= '2000-01-01'
    AND p_content IS NOT NULL AND p_content <> ''
  ) THEN
    RAISE SQLSTATE 'U0002' USING MESSAGE = 'Invalid Parameter';
  END IF;

  -- 処理
END;
$FUNCTION$ LANGUAGE plpgsql;

毎回書くのは大変なので、共通化したいです。以下のようにします。

CREATE OR REPLACE FUNCTION uv_set_test (
  p_uuid UUID DEFAULT NULL
  ,p_start_at TIMESTAMPTZ DEFAULT NULL
  ,p_content TEXT DEFAULT NULL
) RETURNS VOID AS $FUNCTION$
DECLARE
BEGIN
  -- パラメーターチェック
  PERFORM uv_check_parameter(
    p_ary := ARRAY[
      ('uuid', p_uuid IS NOT NULL)
      ,('start_at', p_start_at IS NOT NULL AND p_start_at >= '2000-01-01')
      ,('content', p_content IS NOT NULL AND p_content <> '')
    ]::type_uv_check_parameter[]
  );

  -- 処理
END;
$FUNCTION$ LANGUAGE plpgsql;

結果は以下の通りです。

SELECT * FROM uv_set_test();

ERROR:  Invalid parameter uuid, start_at, content

p_aryのパラメーターはエラーの時に表示する文字列と満たすべき条件になります。
条件が満たされない場合にペアの文字列が表示されます。
複数件チェックしてエラーを返すようにします。

DROP TYPE IF EXISTS type_uv_check_parameter CASCADE;
CREATE TYPE type_uv_check_parameter AS (
  name TEXT
  ,value BOOLEAN
);
CREATE OR REPLACE FUNCTION uv_check_parameter(
  p_ary type_uv_check_parameter[] DEFAULT NULL
  ,p_message TEXT DEFAULT 'Invalid parameter '
) RETURNS VOID AS $FUNCTION$
DECLARE
  w_invalid_name_ary TEXT[] := ARRAY[]::TEXT[];
  w_length BIGINT := COALESCE(array_length(p_ary, 1), 0);
BEGIN
  -- 入力パラメーターチェック
  IF w_length = 0 THEN
    RAISE SQLSTATE 'U0002' USING MESSAGE = p_message || 'ary is empty';
  END IF;

  FOR i IN 1..w_length LOOP
    IF p_ary[i].value IS TRUE THEN
      NULL;
    ELSE
      w_invalid_name_ary:= w_invalid_name_ary || p_ary[i].name;
    END IF;
  END LOOP;

  IF COALESCE(array_length(w_invalid_name_ary, 1), 0) > 0 THEN
    RAISE SQLSTATE 'U0002' USING MESSAGE = p_message || array_to_string(w_invalid_name_ary, ', ');
  END IF;
END;
$FUNCTION$ LANGUAGE plpgsql;
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?