カスタムタイプを作成しました。
CREATE TYPE my_type as(name text, street text, location text);
そのような型の初期化は簡単です:
SELECT ROW('a', 'b', 'c')::my_type;
型を部分的に初期化する簡単な方法があるかどうか、つまり、言及されていないすべての列が暗黙的にnullに設定されているかどうか疑問に思っています。疑似コードでは、次のようになります。
SELECT ROW('a', 'c')::my_type(name, location);
さらに、列が正しい順序で言及されていない場合に型を初期化する方法もありますか?疑似コードでは、次のようになります。
SELECT ROW('c', 'a', 'b')::my_type(location, name, street);
タイプ定義に基づくコード例:
_CREATE TYPE my_type AS (name text, street text, location text);
_
構文は不可能です(すでにご存じのとおり)。 プレーンキャスト は、フィールドの(部分的な)リストを許可しません。
SELECT ROW('a', 'c')::my_type(name, location);
プレーンSQLキャスト式では、欠落しているフィールドにNULL値(またはその他のデフォルト)を指定する必要があります。
_SELECT ROW('a', NULL, 'c')::my_type;
_
または、入力として行型リテラルを使用します。
_SELECT '(a,NULL,c)'::my_type;
_
INSERT
または UPDATE
ステートメントは、複合タイプのフィールドを個別にターゲットにすることができます。 (基になる型はターゲットから派生します。)デモ:
_CREATE TABLE tbl (tbl_id serial, comp my_type);
INSERT INTO tbl (comp.name, comp.location) VALUES ('a', 'c')
UPDATE tbl
SET comp.name = 'X'
, comp.street = 'Y'
WHERE tbl_id = 1;
_
明示的に入力されていないフィールドは、デフォルトでNULLになります。 (タイプが異なるdefaultでない限り、これは一般的ではありません。)
DELETE
の場合は不可能です。これにより、常に行全体が削除されます。論理的には、サブフィールドNULL
を設定することになります。
_UPDATE tbl
SET comp.name = NULL
WHERE tbl_id = 1;
_
通常、手続き型言語関数で変数を使用します-デフォルトPL/pgSQL。そこに _SELECT INTO
_ があります。また、複合タイプのフィールドを個別にアドレス指定できます。デモ:
_DO
$$
DECLARE
_var my_type;
BEGIN
SELECT INTO _var.location, _var.name -- in any chosen order
'c', 'a';
RAISE NOTICE '%', _var;
END
$$
_
db <> fiddle ここ
PL/pgSQLの割り当てを_SELECT INTO
_およびSQLコマンド_SELECT INTO
_と混同しないでください(まったく使用しないでください。代わりに_CREATE TABLE AS
_を使用してください)。見る:
関連する、より洗練されたトリック:
#=
_演算子のデモ)はい。これは任意のタイプを使用して行うことができます
それはコンストラクタがrecord
を取り、マージをサポートします(またはPostgreSQLが「連結する」(||
))。この例はhstore
です。
複合型で、レコードの操作をサポートする任意の型を使用します。思い浮かぶ2つのオプションは、jsonb
とhstore
です。
jsonb
-- In a single call to jsonb_populate_record
SELECT jsonb_populate_record(
null::my_type,
jsonb_build_object('name', 'Evan')
);
-- With a subsequent merge after construction
SELECT jsonb_populate_record(
null::my_type,
'{}'
) || jsonb_build_object('name', 'Evan');
hstore
hstore
は、実際にこれを行で直接実行することをサポートしています。
-- With single-call methods to #= or populate_record
CREATE EXTENSION hstore;
SELECT null::my_type #= hstore('name', 'Evan');
SELECT populate_record(null::my_type, hstore('name', 'Evan'))
最初のオプションは次のようになります。
-- With a subsequent merge after construction
CREATE EXTENSION hstore;
SELECT hstore(null::my_type) || hstore('name', 'Evan');