Postgresql:使用索引类型作为数据类型?

时间:2015-03-28 18:14:44

标签: 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 | 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"

任何解决方案?

1 个答案:

答案 0 :(得分:1)

只是为了说明我想要实现的目标,这就是我找到的临时解决方案。这很丑,但很嘿,它有效......

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)