PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zwróć wiele pól jako rekord w PostgreSQL z PL/pgSQL

Nie używaj CREATE TYPE do zwracania wyniku polimorficznego. Zamiast tego używaj i nadużywaj typu RECORD. Sprawdź 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;

Zwróć uwagę na to, że opcjonalnie może zwrócić dwa lub trzy kolumny w zależności od danych wejściowych.

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 sieje spustoszenie w kodzie, więc używaj stałej liczby kolumn, ale jest to śmiesznie przydatne do zwracania opcjonalnych komunikatów o błędach z pierwszym parametrem zwracającym powodzenie operacji. Przepisano przy użyciu stałej liczby kolumn:

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;

Prawie do epickiej gorączki:

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 podzielić to na wiele wierszy, aby wybrana warstwa ORM mogła przekonwertować wartości na natywne typy danych wybranego języka? Gorąco:

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)

Jest to jedna z najfajniejszych i najczęściej nieużywanych funkcji PostgreSQL. Proszę o rozpowszechnienie informacji.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lista kolumn z indeksami w PostgreSQL

  2. INSERT INTO ... RETURNING - niejednoznaczne odniesienie do kolumny

  3. pgAdmin III Dlaczego wyniki zapytań są skracane?

  4. Klauzula ORDER BY ... USING w PostgreSQL

  5. Ustaw puste ciągi ('') na NULL w całej bazie danych