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
役立ちます。詳細: