PostgreSQLの関数でパラメータのチェックを行う
引き続きSQL関連のネタを書いてみたいと思います。
Javaでクラス外から参照出来るpublicなメソッドを作成する時は、値のチェックとエラーメッセージを行うように心がけています。 これは、クライアントへ想定外の利用を正しく伝えるためです。
public String doSomething(int id, String name) { if (id <= 0) { throw new IllegalArgumentException("idは0以上を指定して下さい。id:" + id); } if (name == null || name.isEmpty()) { throw new IllegalArgumentException("nameが空です。name:" + name); } if (name.length() < 8) { throw new IllegalArgumentException("nameは8文字以上を指定して下さい。name:" + name); } .... }
正常な処理が出来ないことを伝える方法としてこの場合nullを返す等も考えられますが、クライアント側で正常な値であるか判別する必要があります。 仮に判別を行わなかった場合、nullが値として利用されてしまい思わぬ障害を引き起こす可能性があります。 この例ではIllegalArgumentExceptionをスローしていますが、独自の例外を定義する場合もあると思います。
これと同様のことを、SQLの関数で実装してみました。
CREATE OR REPLACE FUNCTION do_something(id NUMERIC, name VARCHAR) RETURNS CHARACTER VARYING AS ' BEGIN IF id <= 0 THEN RAISE EXCEPTION ''idは0以上を指定して下さい。id:%'', id; END IF; IF name IS NULL OR LENGTH(name) <= 8 THEN RAISE EXCEPTION ''nameは8文字以上を指定して下さい。name:%'', name; END IF; .... END; ' language 'plpgsql';
値のチェックを行い、"RAISE EXCEPTION"でエラーメッセージを出力します。 Javaの実装と若干異なりますが、引数の範囲のチェックを行っています。
実行すると、以下のようになります。
postgres=> select do_something(1, '1234'); ERROR: nameは8文字以上を指定して下さい。name:1234
SQLでエラーが発生することで、トランザクションをロールバックさせる対処を取ることが出来ます。 これで、意図しない処理が行われることが無くなります。