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

Върнете SETOF редове от функцията PostgreSQL

Функция дезинфекция

Това, което имате в момента, може да бъде опростено/дезинфекцирано до:

CREATE OR REPLACE FUNCTION func_a (username text = '', databaseobject text = '')
  RETURNS ????
  LANGUAGE plpgsql AS
$func$
BEGIN
   RETURN QUERY EXECUTE
   format ('SELECT * FROM %s v1 LEFT JOIN %I v2 USING (id)'
         , CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
         , databaseobject);
END
$func$;

Нуждаете се само от допълнителни екземпляри на BEGIN ... END в тялото на функцията, за да стартирате отделни кодови блокове със собствен обхват, което рядко е необходимо.

Стандартният оператор за конкатенация на SQL е || . + е "творческо" допълнение на бившия ви доставчик.

Не използвайте CaMeL-case идентификатори, освен ако не ги цитирате. Най-добре не ги използвайте изобщо Вижте:

  • Именната на колоните в PostgreSQL зависят ли от малките букви?

varchar(4000) също така е съобразена със специфично ограничение на SQL Server. Той няма специфично значение в Postgres. Използвайте само varchar(4000) ако наистина имате нужда от ограничение от 4000 знака. Бих използвал просто text - с изключение на това, че изобщо не се нуждаем от никакви променливи тук, след опростяване на функцията.

Ако не сте използвали format() , но вижте ръководството тук.

Тип връщане

Сега, за действителния ви въпрос:Типът на връщане за динамична заявка може да бъде труден, тъй като SQL изисква това да бъде декларирано най-късно в момента на повикване. Ако имате таблица или изглед или съставен тип във вашата база данни, които вече съответстват на списъка с дефиниции на колони, можете просто да използвате това:

CREATE FUNCTION foo()
  RETURNS SETOF my_view AS
...

В противен случай напишете списъка с дефиниции на колони с out с (най-простият) RETURNS TABLE :

CREATE FUNCTION foo()
  RETURNS TABLE (col1 int, col2 text, ...) AS
...

Ако правите типа ред, докато вървите, можете да върнете анонимни записи:

CREATE FUNCTION foo()
  RETURNS SETOF record AS
...

Но тогава трябва да предоставяте списък с дефиниции на колони с всяко извикване, така че почти никога не го използвам.

Не бих използвал SELECT * да започнем с. Използвайте окончателен списък с колони, за да върнете и съответно декларирайте своя тип връщане:

CREATE OR REPLACE FUNCTION func_a(username text = '', databaseobject text = '')
  RETURNS TABLE(col1 int, col2 text, col3 date)
  LANGUAGE plpgsql AS
$func$
BEGIN
   RETURN QUERY EXECUTE
   format ($f$SELECT v1.col1, v1.col2, v2.col3
              FROM %s v1 LEFT JOIN %I v2 USING (id)$f$
         , CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
         , databaseobject);
END
$func$;

За напълно динамични заявки помислете за начало на изграждането на заявката във вашия клиент, вместо да използвате функция.

Първо трябва да разберете основите:

  • Рефакторирайте функция PL/pgSQL, за да върнете резултатите от различни SELECT заявки
  • PL/pgSQL в ръководството на Postgres

След това има по-разширени опции с полиморфни типове, които ви позволяват да предадете връщания тип по време на повикване. Повече в последната глава на:

  • Рефакторирайте функция 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. Първични ключове с Apache Spark

  2. Как работи current_date в PostgreSQL

  3. Cloud9 постгрес

  4. Мога ли автоматично да създам таблица в PostgreSQL от csv файл със заглавки?

  5. Множество CTE в една заявка