plpgsql言語の関数で、次のものがあります。
"col" CHARACTER VARYING = 'a';
(することができます'b'
)"rec" RECORD;
保有記録:(SELECT 1 AS "a", 2 AS "b")
"res" INTEGER;
の名前付き列を参照する必要があり"col"
ます"rec"
。したがって、"col"
を'b'
参照"rec"."b"
し、その値を に保存します"res"
。
plpgsql言語の関数で、次のものがあります。
"col" CHARACTER VARYING = 'a';
(することができます'b'
)"rec" RECORD;
保有記録:(SELECT 1 AS "a", 2 AS "b")
"res" INTEGER;
の名前付き列を参照する必要があり"col"
ます"rec"
。したがって、"col"
を'b'
参照"rec"."b"
し、その値を に保存します"res"
。
plpgsqlでは、匿名レコードタイプの列を名前で参照することはできません。ステートメントの例で列のエイリアスを綴っていてもSELECT
、それらは単なるノイズであり、破棄されます。
レコードタイプの要素を名前で参照する場合は、既知のタイプを使用する必要があります。タイプを作成して使用します。
CREATE TYPE my_composite_type(a int, b int);
または、既存のテーブルに関連付けられている行タイプを使用します。テーブル名はデータ型として記述できます。
DECLARE
rec my_composite_type;
...
次に、の値を識別子として使用するための条件文または動的SQLが必要です。"col"
条件付きステートメント:
IF col = 'a' THEN
res := rec.a;
ELSIF col = 'b' THEN
res := rec.b;
ELSE
RAISE EXCEPTION 'Unexpected value in variable "col": %', col;
END IF;
考えられる2つのケースについては、それが方法です。
または動的SQL:
EXECUTE 'SELECT $1.' || col
INTO res
USING rec;
ここでは問題はありませんが、動的SQLを使用したSQLインジェクションには注意してください。任意のデータを保持できる場合は、またはcol
でエスケープする必要がありますquote_ident()
format()
動的SQLを使用して、より強力でありながらトリッキーなバリアントを示します。
テスト用の(一時的な!)既知のタイプを作成するための迅速で汚い方法:
CREATE TEMP TABLE rec_ab(a int, b int);
働き:
CREATE OR REPLACE FUNCTION f_test()
RETURNS integer AS
$func$
DECLARE
col text := 'a'; -- can be 'b'
rec rec_ab;
res int;
BEGIN
rec := '(1, 2)'::rec_ab;
EXECUTE 'SELECT $1.' || col
INTO res
USING rec;
RETURN res;
END
$func$
LANGUAGE plpgsql VOLATILE;
電話:
SELECT f_test();
戻り値:
f_test
----
1