sql >> Database >  >> RDS >> PostgreSQL

Retourneer meerdere velden als een record in PostgreSQL met PL/pgSQL

Gebruik CREATE TYPE niet om een ​​polymorf resultaat te retourneren. Gebruik en misbruik in plaats daarvan het RECORD-type. Check it out:

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;

Let op dat het optioneel twee . kan retourneren of drie kolommen afhankelijk van de invoer.

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)

Dit veroorzaakt grote schade aan de code, dus gebruik een consistent aantal kolommen, maar het is belachelijk handig voor het retourneren van optionele foutmeldingen waarbij de eerste parameter het succes van de bewerking retourneert. Herschreven met een consistent aantal kolommen:

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;

Bijna tot epische 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)

Maar hoe splitst u dat op in meerdere rijen, zodat uw ORM-laag naar keuze de waarden kan converteren naar de oorspronkelijke gegevenstypen van uw taal naar keuze? De hotness:

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)

Dit is een van de coolste en meest onderbenutte functies in PostgreSQL. Vertel het alsjeblieft.



  1. Hoe impliciete transacties werken in SQL Server

  2. Comprimeer een specifieke partitie binnen een tabel in SQL Server (T-SQL)

  3. Lijst met datumnotatiespecificaties in MySQL

  4. Veelvoorkomende MySql-interviewvragen en -antwoorden voor frisser + ervaren