PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PL/Python &postgreSQL:Кой е най-добрият начин да върнете таблица с много колони?

Опитайте това:

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';

което връща:

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)

Нещо, което трябва да имате предвид за MPP като Greenplum и HAWQ, е да се стремите към функции, които приемат данни като аргумент и връщат резултат, вместо да генерират данните в самата функция. Един и същи код се изпълнява във всеки сегмент, така че понякога може да има нежелани странични ефекти.

Актуализация за SETOF вариант:

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';

Забележете, че за да използвам същите данни от оригиналния пример, трябваше да направя псевдоним на всяка от колоните със съответните имена в myType . Освен това ще трябва да изброите всички колони на mysales ако вървите по този маршрут - няма лесен начин за CREATE TYPE foo LIKE tableBar въпреки че може да можете да използвате това, за да облекчите част от ръчната работа по изброяване на всички имена/типове:

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 ;

което връща:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. недефиниран индекс за бисквитка в някои браузъри

  2. Heroku on Rails - Невалиден DATABASE_URL

  3. Postgresql индекс на xpath израз не дава ускорение

  4. Продължаване на транзакция след грешка при нарушение на първичния ключ

  5. Postgresql конектори, използващи VC++