sql >> Databáze >  >> RDS >> PostgreSQL

Vraťte více polí jako záznam v PostgreSQL s PL/pgSQL

K vrácení polymorfního výsledku nepoužívejte CREATE TYPE. Místo toho použijte a zneužijte typ RECORD. Podívejte se na to:

CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
DECLARE 
  ret RECORD;
BEGIN
  -- Arbitrary expression to change the first parameter
  IF LENGTH(a) < LENGTH(b) THEN
      SELECT TRUE, a || b, 'a shorter than b' INTO ret;
  ELSE
      SELECT FALSE, b || a INTO ret;
  END IF;
RETURN ret;
END;$$ LANGUAGE plpgsql;

Věnujte pozornost skutečnosti, že může volitelně vrátit dva nebo tři sloupce v závislosti na vstupu.

test=> SELECT test_ret('foo','barbaz');
             test_ret             
----------------------------------
 (t,foobarbaz,"a shorter than b")
(1 row)

test=> SELECT test_ret('barbaz','foo');
             test_ret             
----------------------------------
 (f,foobarbaz)
(1 row)

To způsobí zkázu v kódu, takže používejte konzistentní počet sloupců, ale je to směšně užitečné pro vracení volitelných chybových zpráv s prvním parametrem, který vrací úspěšnost operace. Přepsáno pomocí konzistentního počtu sloupců:

CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
DECLARE 
  ret RECORD;
BEGIN
  -- Note the CASTING being done for the 2nd and 3rd elements of the RECORD
  IF LENGTH(a) < LENGTH(b) THEN
      ret := (TRUE, (a || b)::TEXT, 'a shorter than b'::TEXT);
  ELSE
      ret := (FALSE, (b || a)::TEXT, NULL::TEXT);
   END IF;
RETURN ret;
END;$$ LANGUAGE plpgsql;

Téměř k epické horkosti:

test=> SELECT test_ret('foobar','bar');
   test_ret    
----------------
 (f,barfoobar,)
(1 row)

test=> SELECT test_ret('foo','barbaz');
             test_ret             
----------------------------------
 (t,foobarbaz,"a shorter than b")
(1 row)

Ale jak to rozdělit do více řádků, aby vaše zvolená vrstva ORM mohla převádět hodnoty do nativních datových typů vašeho jazyka? Horkost:

test=> SELECT a, b, c FROM test_ret('foo','barbaz') AS (a BOOL, b TEXT, c TEXT);
 a |     b     |        c         
---+-----------+------------------
 t | foobarbaz | a shorter than b
(1 row)

test=> SELECT a, b, c FROM test_ret('foobar','bar') AS (a BOOL, b TEXT, c TEXT);
 a |     b     | c 
---+-----------+---
 f | barfoobar | 
(1 row)

Toto je jedna z nejlepších a nejvíce málo využívaných funkcí v PostgreSQL. Prosím, šiřte to dál.



  1. Jak se spouštějí paralelní plány – část 5

  2. Rozbalovací nabídka přístupu TreeView ImageCombo

  3. Jak vytvořit složený primární klíč v MySQL

  4. Vrátí nečíselné hodnoty ze sloupce databáze PostgreSQL