PostgreSQL 例外を処理するエレガントな方法はありますか? 質問する

PostgreSQL 例外を処理するエレガントな方法はありますか? 質問する

PostgreSQL では、例外が発生した場合に空の結果を返す安全なラッピング メカニズムを作成したいと思います。次のことを考慮してください。

SELECT * FROM myschema.mytable;

クライアント アプリケーションで safe-wrapping を実行できます。

try {
    result = execute_query('SELECT value FROM myschema.mytable').fetchall();
}
catch(pg_exception) {
    result = []
}

しかし、SQL で直接そのようなことを実行できるでしょうか? 次のコードを動作させたいのですが、ブロックに入れる必要があるようでDO $$ ... $$、ここで迷ってしまいます。

BEGIN
    SELECT * FROM myschema.mytable;
EXCEPTION WHEN others THEN
    SELECT unnest(ARRAY[]::TEXT[])
END

ベストアンサー1

PL/pgSQL における例外処理

PL/pgSQLコードは常にBEGIN ... ENDブロックDO。これは文や関数の本体の中に配置できます。ブロックは内部にネストできますが、通常の SQL と混同しないでください。

各ブロックにはオプションEXCEPTIONで例外処理の節を含めることができますが、例外をトラップする必要がある関数はコストが高くなるため、事前に例外を避けるのが最善です。Postgresは、SQLと同様に、例外が発生する前のトランザクションのポイントにロールバックする可能性に備える必要があります。SAVEPOINTマニュアル:

句を含むブロックは、EXCEPTION句を含まないブロックよりも、開始と終了に非常に多くのコストがかかります。したがって、EXCEPTION必要に応じて使用しないでください。

例:

方法避ける例の例外

DOステートメントは何も返すことができません。作成する関数テーブル名とスキーマ名をパラメータとして受け取り、必要なものを返します。

CREATE OR REPLACE FUNCTION f_tbl_value(_tbl text, _schema text = 'public')
  RETURNS TABLE (value text)
  LANGUAGE plpgsql AS
$func$
DECLARE
   _t regclass := to_regclass(_schema || '.' || _tbl);
BEGIN
   IF _t IS NULL THEN
      value := ''; RETURN NEXT;    -- return single empty string
   ELSE
      RETURN QUERY EXECUTE
      'SELECT value FROM ' || _t;  -- return set of values
   END IF;
END
$func$;

電話:

SELECT * FROM f_tbl_value('my_table');

または:

SELECT * FROM f_tbl_value('my_table', 'my_schema');

textテーブルが存在しない場合は、単一の列または空の文字列を含む行のセットが必要であると仮定します。

また、指定されたテーブルが存在する場合は列がvalue存在すると想定します。これもテストできますが、それを要求していません。

両方の入力パラメータは大文字と小文字を区別二重引用符で囲むと識別子はSQL文で処理されます

私の例では、スキーマ名はデフォルトで になっています'public'。必要に応じて調整してください。スキーマを完全に無視して、現在のデフォルトにすることもできます。search_path

to_regclass()Postgresの新機能9.4旧バージョンの場合は以下を代用してください:

IF EXISTS (
   SELECT FROM information_schema.tables 
   WHERE  table_schema = _schema
   AND    table_name = _tbl
   ) THEN ...

これは実はより正確なまさに必要なものをテストするからです。その他のオプションと詳細な説明:

動的 SQL を使用する場合は、常に SQL インジェクションを防御してください。ここでは、キャストがregclass役立ちます。詳細:

おすすめ記事