sql >> Database teknologi >  >> RDS >> PostgreSQL

Returner flere felter som en post i PostgreSQL med PL/pgSQL

Brug ikke CREATE TYPE til at returnere et polymorfisk resultat. Brug og misbrug typen RECORD i stedet. Tjek det ud:

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ær opmærksom på, at den valgfrit kan returnere to eller tre kolonner afhængigt af input.

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)

Dette forårsager kaos på kode, så brug et ensartet antal kolonner, men det er latterligt praktisk til at returnere valgfri fejlmeddelelser med den første parameter, der returnerer operationens succes. Omskrevet med et ensartet antal kolonner:

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;

Næsten til episk hotness:

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)

Men hvordan deler du det op i flere rækker, så dit udvalgte ORM-lag kan konvertere værdierne til dit foretrukne sprogs oprindelige datatyper? Det varme:

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)

Dette er en af ​​de fedeste og mest underudnyttede funktioner i PostgreSQL. Spred venligst budskabet.



  1. Hvor forskellig er PostgreSQL fra MySQL?

  2. PostgreSQL-opdateringer med flere rækker i Node.js

  3. YEAR() Eksempler i SQL Server (T-SQL)

  4. Brug af pivot på flere kolonner i en Oracle-række