【问题标题】:How to add new elements to an array of a user-defined type?如何将新元素添加到用户定义类型的数组中?
【发布时间】:2019-02-28 17:50:11
【问题描述】:

我已将一些存储过程从 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[]);

在甲骨文中:

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

您能告诉我如何将下面最后两行代码转换为 PostgreSQL 吗?

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

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

【问题讨论】:

    标签: arrays postgresql


    【解决方案1】:

    您可以使用|| 连接运算符简单地将值附加到数组中。确保将变量初始化为一个空数组(否则它会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() ;
    

    【讨论】:

    • 非常感谢。我更新了函数以返回 RETURNS ut_merci_row[] 而不是 RETURNS UT_MERCI_TABLE。并且返回结果是一个 ut_merci_row 对象数组?我们不能使用 RETURNS UT_MERCI_TABLE 吗?
    • @ThaiLe:你不需要ut_merci_table 的杂乱无章,只需返回该记录的数组即可。或者更好的是,不要将函数定义为 returns table 并摆脱缓慢的光标处理。
    • 非常感谢您的解释。我会用这些更新函数。
    【解决方案2】:

    第二种类型定义比较多余,直接使用ut_merci_row[]即可。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 2019-10-06
      • 2018-05-03
      • 1970-01-01
      相关资源
      最近更新 更多