如何使用复合类型更新Postgresql表

时间:2017-05-02 17:10:00

标签: postgresql postgres-plpython

我正在尝试使用复合键更新表,但无法弄清楚 语法。我有一个表定义为:

In [1]: x = 10

In [2]: y = 4

In [3]: x + y
Out[3]: 14

In [4]: _3
Out[4]: 14

我可以验证我的定义类型是否有效:

create schema test;
create type test.ra_dec as (f1 double precision, f2 double precision);
create table test.pos_vel(
      xp double precision,
      yp double precision,
      xv double precision,
      yv double precision
);
insert into test.pos_vel(xp,yp,xv,yv) values
       (1,2,5,10),
       (2,3,10,20),
       (3,4,20,40);

但我无法弄清楚如何更新我的桌子。

gsh=# select cast( (100,200) as test.ra_dec);
    row    
-----------
 (100,200)
(1 row)

我知道这个trival示例我可以在不使用复合类型的情况下完成它,但出于速度原因,我想在pl / python中定义一个函数并让它返回一个复合类型,所以我需要弄清楚正确的语法。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

-- drop schema if exists test cascade;
create schema test;
create type test.ra_dec as (f1 double precision, f2 double precision);

-- Your function here
create function test.f() returns test.ra_dec language sql as $$
  select (100,200)::test.ra_dec $$;

create table test.pos_vel(
      xp double precision,
      yp double precision,
      xv double precision,
      yv double precision
);
insert into test.pos_vel(xp,yp,xv,yv) values
       (1,2,5,10),
       (2,3,10,20),
       (3,4,20,40);

update test.pos_vel set (xv,yv) = (select * from test.f());

更新

因为在PostgreSQL 9.5中引入了针对此类情况的子选择,所以它在早期版本中不起作用。有两种解决方法:

update test.pos_vel set (xv,yv) = ((test.f()).f1, (test.f()).f2);

update test.pos_vel set (xv,yv) = (t.f1, t.f2) from (select * from test.f()) t;

在8.4上进行测试:http://dbfiddle.uk/?rdbms=postgres_8.4&fiddle=0a4927ed804b76442a69f8259cca1929