sql >> Databasteknik >  >> RDS >> PostgreSQL

PL/Python &postgreSQL:Vad är det bästa sättet att returnera en tabell med många kolumner?

Prova detta:

CREATE OR REPLACE FUNCTION myFunc02() 
RETURNS TABLE (like mysales) AS 
$$
rv = plpy.execute('SELECT * FROM mysales ORDER BY id;', 5)
d  = rv.nrows()
return rv[0:d]
$$ LANGUAGE 'plpythonu';

som returnerar:

gpadmin=# SELECT * FROM myFunc02();                             
 id | year | qtr | day |    region
----+------+-----+-----+---------------
  1 | 2014 |   1 |   1 | north america
  2 | 2002 |   2 |   2 | europe
  3 | 2014 |   3 |   3 | asia
  4 | 2010 |   4 |   4 | north-america
  5 | 2014 |   1 |   5 | europe
(5 rows)

Något att tänka på för MPP som Greenplum och HAWQ är att sträva efter funktioner som tar data som ett argument och returnerar ett resultat, snarare än att ursprunget till data i själva funktionen. Samma kod körs på varje segment så ibland kan det uppstå oavsiktliga biverkningar.

Uppdatering för SETOF variant:

CREATE TYPE myType AS (id integer, x integer, y integer, s text);

CREATE OR REPLACE FUNCTION myFunc02a() 
RETURNS SETOF myType AS 
$$

# column names of myType ['id', 'x', 'y', 's']
rv = plpy.execute("SELECT id, year as x, qtr as y, region as s FROM mysales ORDER BY id", 5)
d  = rv.nrows()

return rv[0:d]
$$ LANGUAGE 'plpythonu';

Observera, för att använda samma data från det ursprungliga exemplet, var jag tvungen att aliasa var och en av kolumnerna till motsvarande namn i myType . Du måste också räkna upp alla kolumner i mysales om du går den här vägen - det finns inget enkelt sätt att CREATE TYPE foo LIKE tableBar även om du kanske kan använda detta för att underlätta en del av det manuella arbetet med att räkna upp alla namn/typer:

select string_agg(t.attname || ' ' || t.format_type || ', ') as columns  from 
(
SELECT a.attname,
  pg_catalog.format_type(a.atttypid, a.atttypmod),
  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
   FROM pg_catalog.pg_attrdef d
   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),
  a.attnotnull, a.attnum,
  a.attstorage ,
  pg_catalog.col_description(a.attrelid, a.attnum)
FROM pg_catalog.pg_attribute a
LEFT OUTER JOIN pg_catalog.pg_attribute_encoding e
ON   e.attrelid = a .attrelid AND e.attnum = a.attnum
WHERE a.attrelid = (SELECT oid FROM pg_class WHERE relname = 'mysales') AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
) t ;

som returnerar:

                              columns
-------------------------------------------------------------------
 id integer, year integer, qtr integer, day integer, region text,
(1 row)



  1. Kontrollera om en tabell refereras av en främmande nyckel i SQL Server med OBJECTPROPERTY()

  2. Utmaningslösningar för nummerseriegenerator – del 3

  3. MySQL - BETWEEN operator med FLOAT(10,6) fungerar som> och <, istället för>=och <=

  4. Anropar en annan PL/SQL-procedur inom en procedur