7

Meine letzte Frage Passing an array to stored to postgres war ein bisschen unklar. Nun, um mein Ziel zu verdeutlichen:Unnest mehrere Arrays parallel

Ich möchte eine Postgres gespeicherte Prozedur erstellen, die zwei Eingabeparameter akzeptiert. Eine wird eine Liste von einigen Mengen wie zum Beispiel (100, 40.5, 76) sein und die andere wird eine Liste von einigen Rechnungen sein('01-2222-05','01-3333-04','01-4444-08'). Danach möchte ich diese zwei Listen von Zahlen und Zeichen verwenden und etwas damit machen. Zum Beispiel möchte ich jeden Betrag aus diesem Zahlenfeld nehmen und ihn der entsprechenden Rechnung zuordnen.

So etwas in Oracle würde wie folgt aussehen:

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); 

Natürlich sind die zwei Typen SIMPLEARRAYTYPE und NUMBER_TABLE früher in DB definiert sind.

+0

Was genau unklar ist? Wie nennt man diese Art von Funktionen? Sie können die Array-Konstruktoren http://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS verwenden oder Sie können ihre Eingabedarstellung in eine Zeichenfolge schreiben (verwenden Sie dann optional Casting)) http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO – pozs

+0

Ich weiß nicht, wie man gespeicherte Proc mit diesen Arten von Eingabeparametern erstellt. – Maki

+2

Das ist auch in Ihren vorherigen Fragen abgedeckt (zB http://stackoverflow.com/questions/27708234/pl-pgsql-control-structures-for-lists-arrays) - Sie können den Standard verwenden Kompatibel ' ARRAY', oder die PostgreSQL spezifische' [] 'Syntax. http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-DECLARATION – pozs

Antwort

10

Sie werden Liebe diese neue Funktion von Postgres 9.4:

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

unnest() mit der viel zu erwartenden (zumindest von mir) Fähigkeit, mehrere Arrays parallel zu verschmelzen sauber. The manual:

erweitern Sie mehrere Arrays (möglicherweise von verschiedenen Typen) zu einer Reihe von Zeilen. Dies ist nur in der FROM-Klausel erlaubt;

Es ist eine spezielle Implementierung des neuen ROWS FROM feature.

Ihre Funktion kann jetzt nur sein:

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;

Call:

SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[] 
         , '{01-2222-05,01-3333-04,01-4444-08}'::text[]); 

Natürlich kann die einfache Form mit Ebene SQL (keine zusätzliche Funktion) ersetzt werden:

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); 

In früheren Versionen (Postgres 9.

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; 

Caveats der alten Kurzform: 3-), können Sie die weniger elegant und weniger sichere Form verwenden neben völlig Nicht-Standard ist Funktion in der SELECT Liste Set-Rückkehr und sogar UNNEST parallel anstatt ein kartesisches Produkt zu bilden, würde dies fehlschlagen (und standardmäßig ein kartesisches Produkt) für Arrays mit einer ungleichen Anzahl von Elementen. Details in diesen verwandten Antworten:

Dieses Verhalten schließlich wurde mit Postgres hygienisiert. Mehrere Set-Return-Funktionen in der SELECT Liste erzeugen jetzt Zeilen in "lock-step". Siehe:

2

Arrays werden deklariert, indem zum Basisdatentyp [] hinzugefügt wird. Sie erklären, sie als Parameter auf die gleiche Weise regelmäßige Parameter erklären:

Die folgende Funktion ein Array von ganzen Zahlen und und Array von Strings akzeptiert und wird einige Dummy-Text zurück:

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 Demo: http://sqlfiddle.com/#!15/fdb8d/1

+0

Ich habe einen Fehler erhalten, als ich diesen Anruf versuchte. – Maki

+0

Sorry, mein Fehler, es ist okay. Kann ich FOREACH über Text-Array verwenden? – Maki

+0

Kann ich FOREACH über Text-Array in Postgres verwenden? – Maki