Postgresql:使用索引类型作为数据类型?
我试图从一行中提取作为表主索引一部分的字段。(记录在案) 例如,如果我创建如下表:Postgresql:使用索引类型作为数据类型?,postgresql,Postgresql,我试图从一行中提取作为表主索引一部分的字段。(记录在案) 例如,如果我创建如下表: CREATE TABLE t1 (k1 int not null, k2 int not null, label text, PRIMARY KEY(k1, k2)); INSERT INTO t1(k1,k2,label) values (3,5,'hello'); 然后我可以做: SELECT * from json_populate_record(null::t1, '{}'); k1 | k2
CREATE TABLE t1 (k1 int not null, k2 int not null, label text, PRIMARY KEY(k1, k2));
INSERT INTO t1(k1,k2,label) values (3,5,'hello');
然后我可以做:
SELECT * from json_populate_record(null::t1, '{}');
k1 | k2 | label
----+----+-------
| |
(1 row)
……或者我可以
select row_to_json(row) from (select * from t1) as row;
row_to_json
---------------------------------
{"k1":3,"k2":5,"label":"hello"}
(1 row)
但是,我想做:
SELECT * from json_populate_record(null::t1_pkey, '{}');
k1 | k2 |
----+----+
| |
(1 row)
。。。或者
select row_to_json(row::t1_pkey) from (select * from t1) as row;
row_to_json
---------------------------------
{"k1":3,"k2":5}
(1 row)
但是,问题是:
ERROR: type "t1_pkey" does not exist
这种类型可能存在于某个地方,因为:
\d t1_pkey
Index "public.t1_pkey"
Column | Type | Definition
--------+---------+------------
k1 | integer | k1
k2 | integer | k2
primary key, btree, for table "public.t1"
有什么解决办法吗?只是为了明确我想要实现的目标,这是我找到的临时解决办法。它很难看,但是嘿,它很管用
CREATE OR REPLACE
FUNCTION public.pka(in t_oid oid, in t_row anyelement)
RETURNS RECORD
AS
$$
DECLARE
k text;
v text;
keys text[];
sel text[];
i int;
rec record;
BEGIN
SELECT array(SELECT a.attname
FROM pg_index i
JOIN pg_attribute a ON a.attrelid = i.indrelid
AND a.attnum = ANY(i.indkey)
WHERE i.indisprimary AND i.indrelid = t_oid) INTO keys;
i := 0;
FOREACH k IN ARRAY keys
LOOP
i := i + 1;
EXECUTE format('SELECT $1.%s', k) USING t_row INTO v;
sel[i] := concat(quote_literal(v),' as ',k);
END LOOP;
EXECUTE format('SELECT %s', array_to_string(sel, ', '), sel) INTO rec;
return rec;
END;
$$
LANGUAGE 'plpgsql' STABLE;
select to_json(pka('t1'::regclass::oid, row::t1)) from (select * from t1) as row;
to_json
---------------------
{"k1":"3","k2":"5"}
(1 row)
“t1_pkey”不是一种类型。它是索引的名称。t1不是类型。它是表的名称,但是您可以将表名称用作复合行/记录类型。如果你不能用主键定义来做这件事,那将是非常奇怪的,因为数据库整天都在比较和排序主键……从一个删除的答案的评论中,matthieu写道:“我不想要索引列的类型,我想要主键的复合类型”您可以通过使用字符串连接构造
SELECT
,使其一次返回所有所需字段,从而稍微美化一下。但总的想法是正确的,你不可能找到比这更简单的方法。我建议使用information\u schema
而不是直接pg\u catalog
access,这样就可以保护您免受特定版本的更改,但仅此而已。