如何将新元素添加到用户定义类型的数组?

时间:2019-02-28 06:38:53

标签: arrays postgresql

我已将一些存储过程从Oracle转换为PostgreSQL,但遇到以下问题:

我在PostgreSQL中有一个用户定义的类型:

CREATE TYPE ut_merci_row AS (    
   SGLCNTNR varchar(100),
   CODEST_MERCEVARIA varchar(50), 
   CODCICLO smallint 
);

CREATE TYPE ut_merci_table AS (ut_merci_table UT_MERCI_ROW[]);

在Oracle中:

  retTable UT_MERCI_TABLE := UT_MERCI_TABLE();
  .....
  retTable.extend;
  retTable(retTable.last) := UT_MERCI_ROW(rec.SGLCNTNR,rec.CODEST_MERCEVARIA,rec.CODCICLO);

您能建议我如何将下面的2条代码行转换为PostgreSQL吗?

  retTable.extend;
  retTable(retTable.last) := UT_MERCI_ROW(rec.SGLCNTNR,rec.CODEST_MERCEVARIA,rec.CODCICLO);

有人说我们不需要在PostgreSQL中“扩展”集合。

2 个答案:

答案 0 :(得分:0)

第二种类型定义非常多余,只需使用ut_merci_row[]

您不必在PostgreSQL中“扩展”数组,只需将其分配给尚未使用的索引即可。

答案 1 :(得分:0)

您可以简单地使用||串联运算符将值附加到数组。确保将变量初始化为空数组(否则为null

retTable ut_merci_row[] := '{}';

然后在循环中,只需将类型的值附加到数组即可:

retTable := rettable || row(rec.SGLCNTNR,rec.CODEST_MERCEVARIA,rec.CODCICLO)::ut_merci_row;

在Postgres中,尝试模仿Oracle使用游标和自定义类型返回表的复杂方法并不是正确的方法。

但是更好的解决方案是摆脱所有游标处理和数组处理,并返回一组基本类型:

CREATE OR REPLACE FUNCTION uf_getstatomerce1() 
  returns setof ut_merci_row
AS $body$
   SELECT DISTINCT row(m.SGLCNTNR, m.CODEST_MERCEVARIA, 1 as CODCICLO)::ut_merci_row
   from merce.DELIVERY_ORDER_RIF rif
     inner join merce.DELIVERY_ORDER_PARTITA pm on rif.DO_ID = pm.DO_ID
     inner join merce.vPARTITEMERCE m on pm.CODPARTITAMERCE = m.CODPARTITAMERCE;
$body$
LANGUAGE sql
STABLE;

实际上,在Postgres中,您也不需要为此的自定义类型,只需将函数声明为returns table并忽略所有开销:

CREATE OR REPLACE FUNCTION uf_getstatomerce1() 
  returns table (SGLCNTNR varchar, CODEST_MERCEVARIA varchar, CODCICLO smallint )
AS $body$
   SELECT DISTINCT row(m.SGLCNTNR, m.CODEST_MERCEVARIA, 1 as CODCICLO)::ut_merci_row
   from merce.DELIVERY_ORDER_RIF rif
     inner join merce.DELIVERY_ORDER_PARTITA pm on rif.DO_ID = pm.DO_ID
     inner join merce.vPARTITEMERCE m on pm.CODPARTITAMERCE = m.CODPARTITAMERCE;
$body$
LANGUAGE sql
STABLE;

仅返回查询的SQL函数将比游标循环更有效

在两种情况下,您都可以像这样使用它:

select *
from uf_getstatomerce1() ;