为了账号安全,请及时绑定邮箱和手机立即绑定

取消并行嵌套多个数组

/ 猿问

取消并行嵌套多个数组

我的最后一个问题是将数组传递给存储到postgres尚不清楚。现在,澄清我的目标:


我想创建一个Postgres存储过程,该过程将接受两个输入参数。一个将是例如一些金额的列表,(100, 40.5, 76)而另一个将是一些发票的 列表('01-2222-05','01-3333-04','01-4444-08')。之后,我要使用这两个数字和字符列表,并对它们进行处理。例如,我想从此数字数组中提取每个金额并将其分配给相应的发票。


Oracle中的内容如下所示:


SOME_PACKAGE.SOME_PROCEDURE (

    789,

    SYSDATE,

    SIMPLEARRAYTYPE ('01-2222-05','01-3333-04','01-4444-08'), 

    NUMBER_TABLE (100,40.5,76),

    'EUR',      

    1, 

    P_CODE,

    P_MESSAGE);

当然,这两种类型SIMPLEARRAYTYPE和NUMBER_TABLE早在DB中已定义。


查看完整描述

2 回答

?
ABOUTYOU

您会喜欢 Postgres 9.4的这一新功能的:


    unnest(anyarray, anyarray [, ...])

unnest()具有(至少在我看来)备受期待的干净嵌套多个阵列的功能。手册:


将多个数组(可能是不同类型)扩展为一组行。这仅在FROM子句中允许;


这是新ROWS FROM功能的特殊实现。


您的功能现在可以是:


CREATE OR REPLACE FUNCTION multi_unnest(_some_id int

                                      , _amounts numeric[]

                                      , _invoices text[])

  RETURNS TABLE (some_id int, amount numeric, invoice text) AS

$func$

SELECT _some_id, u.* FROM unnest(_amounts, _invoices) u;

$func$ LANGUAGE sql;

呼叫:


SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[] 

                        , '{01-2222-05,01-3333-04,01-4444-08}'::text[]);

当然,可以用简单的SQL替换简单形式(没有附加功能):


SELECT 123 AS some_id, *

FROM unnest('{100, 40.5, 76}'::numeric[]

          , '{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS u(amount, invoice);

在早期版本(Postgres 9.3-)中,可以使用不太优雅和不太安全的形式:


SELECT 123 AS some_id

     , unnest('{100, 40.5, 76}'::numeric[]) AS amount

     , unnest('{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS invoice;

旧时速记形式的警告:除了在SELECT列表中具有set-returning函数的功能是非标准的之外,返回的行数将是每个数组元素数量的最小公倍数(对于不相等的数字,结果令人惊讶)。这些相关答案中的详细信息:


PostgreSQL中的并行unnest()和排序顺序

PostgreSQL中是否有类似zip()函数的东西,它结合了两个数组?

最终,Postgres 10对此行为进行了消毒。SELECT列表中的多个set-returning函数现在以“锁步”方式产生行。


查看完整回答
反对 回复 2019-12-05
?
翻阅古今

通过添加[]到基本数据类型来声明数组。将它们声明为参数的方式与声明常规参数的方式相同:


以下函数接受整数数组和字符串数组,并将返回一些伪文本:


create function array_demo(p_data integer[], p_invoices text[])

  returns text

as

$$

  select p_data[1] || ' => ' || p_invoices[1];

$$

language sql;


select array_demo(array[1,2,3], array['one', 'two', 'three']);

SQLFiddle演示:http ://sqlfiddle.com/#!15/fdb8d/1


查看完整回答
反对 回复 2019-12-05
  • 2 回答
  • 0 关注
  • 230 浏览
我要回答
慕课专栏
更多

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信