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

Деклариране на структурата на кортежа на запис в PL/pgSQL

Смесвате синтаксиса за връщане на SETOF стойности със синтаксис за връщане на един ред или стойност.

-- Свързан въпрос е - как да върна единичния запис 'r' от

Когато декларирате функция с RETURNS TABLE , трябва да използвате RETURN NEXT в тялото, за да върне ред (или скаларна стойност). И ако искате да използвате record променлива, с която трябва да съвпада типът връщане. Вижте примерите за код по-долу.

Връщане на единична стойност или ред

Ако искате да върнете само един ред, няма нужда за запис от недефиниран тип. @Kevin вече демонстрира два начина. Ще добавя опростена версия с OUT параметри:

CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
   AS
$func$
BEGIN
   a := ...;
   b := ...;
END
$func$ LANGUAGE plpgsql;

Дори не е нужно да добавяте RETURN; в тялото на функцията, стойността на декларирания OUT параметрите ще бъдат върнати автоматично в края на функцията - NULL за всеки параметър, който не е бил присвоен.
И не е нужно да декларирате RETURNS RECORD защото това вече е ясно от OUT параметри.

Връщане на набор от редове

Ако всъщност искате да върнете множество редове (включително възможността за 0 или 1 ред), можете да дефинирате типа на връщане като RETURNS ...

  • SETOF some_type , където some_type може да бъде всеки регистриран скаларен или композитен тип.

  • TABLE (col1 type1, col2 type2) - ad hoc определение на типа ред.

  • SETOF record плюс OUT параметри за дефиниране на имена и типове на колони.
    100% еквивалент на RETURNS TABLE .

  • SETOF record без допълнително определение. Но след това върнатите редове са недефинирани и трябва да включите списък с дефиниции на колони с всяко извикване (вижте примера).

Ръководството за типа на записа:

Променливите за запис са подобни на променливите от редов тип, но имат без предварително дефинирана структура. Те поемат действителната структура на реда на реда, който им е присвоен по време на команда SELECT или FOR.

Има още, прочетете ръководството.

Вие можете използвайте променлива на запис, без да присвоявате дефиниран тип, можете дори да върне такива недефинирани записи:

CREATE OR REPLACE FUNCTION my_func()
  RETURNS SETOF record AS
$func$
DECLARE
    r record;
BEGIN
    r := (1::int, 'foo'::text); RETURN NEXT r; -- works with undefined record
    r := (2::int, 'bar'::text); RETURN NEXT r;
END
$func$ LANGUAGE plpgsql;

Обадете се:

SELECT * FROM my_func() AS x(a int, b text);

Но това е много тромаво тъй като трябва да предоставяте списъка с дефиниции на колони при всяко повикване. По принцип може да бъде заменен с нещо по-елегантно:

  • Ако знаете типа към момента на създаване на функцията, декларирайте го веднага (RETURNS TABLE или приятели).

CREATE OR REPLACE FUNCTION my_func()
  RETURNS SETOF tbl_or_type AS
$func$
DECLARE
    r tbl_or_type;
BEGIN
    SELECT INTO tbl_or_type  * FROM tbl WHERE id = 10;
    RETURN NEXT r;  -- type matches

    SELECT INTO tbl_or_type  * FROM tbl WHERE id = 12;
    RETURN NEXT r;

    -- Or simpler:
    RETURN QUERY
    SELECT * FROM tbl WHERE id = 14;
END
$func$ LANGUAGE plpgsql;
  • Ако знаете типа в момента на извикването на функция , има по-елегантни начини за използване на полиморфни типове:
    Рефакторирайте функция PL/pgSQL, за да върнете резултатите от различни SELECT заявки

Въпросът ви не е ясен какво точно ви трябва.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. postgreSQL - in vs any

  2. uWSGI, Flask, sqlalchemy и postgres:SSL грешка:неуспешно декриптиране или лош запис mac

  3. Разбиране на JDBC пакетни операции

  4. Psycopg2 Вмъкване в таблица с заместители

  5. Получавате размер на голям обект в заявка на PostgreSQL?