简体   繁体   English

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

[英]How to add new elements to an array of a user-defined type?

I have converted some stored procedure from Oracle to PostgreSQL but faced the below issue: 我已将一些存储过程从Oracle转换为PostgreSQL,但遇到以下问题:

I have a user-defined type in 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[]);

In Oracle: 在Oracle中:

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

Could you advise me how to convert the 2 last below code lines to PostgreSQL? 您能否建议我如何将下面的最后2行代码转换为PostgreSQL?

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

Someone said that we don't need to "extend" the collection in PostgreSQL. 有人说我们不需要在PostgreSQL中“扩展”集合。

The second type definition is pretty redundant, just use ut_merci_row[] . 第二种类型定义非常多余,只需使用ut_merci_row[]

You don't have to “extend” an array in PostgreSQL, just assign to an index that is not yet used. 您不必在PostgreSQL中“扩展”数组,只需将其分配给尚未使用的索引即可。

You can simply append the value to the array using the || 您可以简单地使用||将值附加到数组。 concatenation operator. 串联运算符。 Make sure you initialize the variable to an empty array (otherwise it would null ) 确保将变量初始化为空数组(否则它将为null

retTable ut_merci_row[] := '{}';

Then in the loop, just append a value of the type to the array: 然后在循环中,只需将类型的值附加到数组即可:

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

Trying to mimic Oracle's complicated way of returning tables with a cursor and custom types is not the right way to do this in Postgres. 在Postgres中,尝试模仿Oracle使用游标和自定义类型返回表的复杂方法并不是正确的方法。

But a much better solution would be to get rid of all that cursor processing and array handling and return a set of the base type: 但是更好的解决方案是摆脱所有游标处理和数组处理,并返回一组基本类型:

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;

In fact, in Postgres you also don't need a custom type for this, just declare the function as returns table and forget all the overhead: 实际上,在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;

The SQL function that simply returns a query will be much more efficient than the cursor loop. 简单地返回查询的SQL函数会游标循环更有效。

In both cases, you can use it like this: 在这两种情况下,您都可以这样使用它:

select *
from uf_getstatomerce1() ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM