これら5つの異なる種類のデータ/シンボルの主な性質を理解することが重要です。 :
1。 'my_tbl'
不明
の文字列リテラル タイプ 。 SQLで使用される場合(plpgsqlコードに埋め込まれているかどうかに関係なく)、コンテキストから派生した型に強制変換されます。 。タイプを判別できない場合は、明示的なキャストが必要になる場合があります。例:'my_tbl' ::text
。
2。 'my_tbl' ::text
タイプtext
にキャストされた同じ文字列リテラル 。テーブルの名前を保持できますが、実際には単なるテキストです。
3。 'my_tbl' ::regclass
オブジェクト識別子(OID)
登録済みのクラスの場合 。表示され、有効なオブジェクト名を表す文字列として入力できます('my_tbl'
)。出力は自動的にスキーマ修飾されます('my_schema.my_tbl'
)および/または二重引用符('"mY_TbL"'
)あいまいまたは違法である場合。通常のテーブルにすることができます 、シーケンス 、表示 、マテリアライズドビュー 、複合タイプ など。この関連する回答の詳細:
4。 my_tbl_var my_tbl
( my_tbl_var my_tbl%ROWTYPE
の略 )
DECLARE
で よく知られているpg_class
に登録する必要があります ( regclass
と同じ 変数)。これは、参照されるオブジェクトのOIDではなく、実際の行タイプです。 my_tbl_var
およびmy_tbl
どちらも識別子です ここで、パラメータ化することはできません。任意の行またはレコードを直接キャストすることもできます:(123、'foo')::my_tbl
5。 my_tbl_varレコード
DECLARE
で 匿名の
あなたは1。を混乱させていました 、3。 および4。 5を使用して解決しました。 代わりに。
しかし、もっとうまくいかない ここ:
-
テーブル全体を選択していますが、行(レコード)変数は一度に1つの行しか保持できません。したがって、最初のものだけが割り当てられて返されます。
ORDER BY
はありませんが 条項では、結果は任意であり、いつでも変更できます。 邪悪な罠。 -
record
を使用しているので タイプの場合、フィールドでテストを実行する前に、割り当てられていることを確認する必要があります。そうしないと、空のテーブルの例外が発生します。この場合、record_var IS NULL
を確認してください。 ほぼ同じ仕事をします。ただし、すべてのフィールドにNULLが含まれる行には、コーナーケースがあります。record_var IS NULL
trueと評価されます。テストではさらに注意が必要ですISNOT NULL
。詳細はこちら:SQLフィドル にデモを追加しました 以下。
-
この関数は単一のスカラー(
boolean
)を返します ) 価値。使用:RETURN false;
代わりに:
RETURN QUERY SELECT false;
機能
CREATE FUNCTION check_valid(_tbl regclass)
RETURNS bool AS
$func$
DECLARE
r record;
_row_ct int;
BEGIN
EXECUTE '
SELECT is_valid, hit_count, hit_limit
FROM ' || _tbl || '
ORDER <whatever>
LIMIT 1' -- replace <whatever> with your sort criteria
INTO r; -- only needed columns
GET DIAGNOSTICS _row_ct = ROW_COUNT;
IF _row_ct = 0 THEN -- necessary, because r may not be assigned
RETURN false;
ELSIF NOT r.is_valid OR r.hit_count > r.hit_limit THEN
RETURN false;
END IF;
RETURN true;
END
$func$ LANGUAGE plpgsql;
SQLフィドル (関数の2つのバリアントと行のデモはNULLです)。
主なポイント
-
GET DIAGNOSTICS
>EXECUTE
を使用した動的ステートメントで行が見つかったかどうかを確認します 。 -
IF
式を簡略化できます。 -
パラメータのタイプは
regclass
です。 、テーブル名だけではありません。このパラメータには誤解を招くような名前「tablename」は使用しません。それはあなたの最初の混乱を増すだけです。それを_tbl
と呼びます 代わりに。
返品もしたい場合 可変行タイプのセット: