我已将一些存储过程从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中“扩展”集合。
答案 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() ;