PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zwróć wiersze SETOF z funkcji PostgreSQL

Funkcja dezynfekcji

To, co obecnie posiadasz, można uprościć/odkazić do:

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

Potrzebujesz tylko dodatkowych wystąpień BEGIN ... END w ciele funkcji, aby rozpocząć oddzielne bloki kodu z własnym zakresem, co jest rzadko potrzebne.

Standardowym operatorem łączenia SQL jest || . + jest "kreatywnym" dodatkiem twojego byłego dostawcy.

Nie używaj identyfikatorów CaMeL-case, chyba że umieścisz je w podwójnym cudzysłowie. Najlepiej w ogóle ich nie używać Zobacz:

  • Czy w nazwach kolumn PostgreSQL jest rozróżniana wielkość liter?

varchar(4000) jest również dostosowany do konkretnego ograniczenia SQL Server. W Postgresie nie ma to szczególnego znaczenia. Używaj tylko varchar(4000) jeśli faktycznie potrzebujesz limitu 4000 znaków. Po prostu użyłbym text - poza tym, że nie potrzebujemy żadnych zmiennych w ogóle tutaj, po uproszczeniu funkcji.

Jeśli nie użyłeś format() , jednak zapoznaj się z instrukcją tutaj.

Typ zwrotu

Teraz, jeśli chodzi o twoje rzeczywiste pytanie:typ zwracany dla zapytania dynamicznego może być trudny, ponieważ SQL wymaga, aby został zadeklarowany najpóźniej w czasie wywołania. Jeśli masz w bazie danych tabelę, widok lub typ złożony, który już pasuje do listy definicji kolumn, możesz po prostu użyć tego:

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

W przeciwnym razie przeliteruj listę definicji kolumn bez out za pomocą (najprostszego) RETURNS TABLE :

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

Jeśli wpisujesz wiersz na bieżąco, możesz zwrócić anonimowe rekordy:

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

Ale wtedy musisz dostarczyć listę definicji kolumn przy każdym wywołaniu, więc prawie nigdy tego nie używam.

Nie użyłbym SELECT * najpierw. Użyj ostatecznej listy kolumn do zwrotu i odpowiednio zadeklaruj typ zwrotu:

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

W przypadku całkowicie dynamicznych zapytań rozważ najpierw zbudowanie zapytania w swoim kliencie, zamiast używania funkcji.

Najpierw musisz zrozumieć podstawy:

  • Refaktoryzuj funkcję PL/pgSQL, aby zwrócić dane wyjściowe różnych zapytań SELECT
  • PL/pgSQL w podręczniku Postgresa

Następnie są bardziej zaawansowane opcje z typami polimorficznymi, które pozwalają przekazać typ zwracany w czasie połączenia. Więcej w ostatnim rozdziale:

  • Refaktoryzuj funkcję PL/pgSQL, aby zwrócić dane wyjściowe różnych zapytań 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. Używanie wielu schematów PostgreSQL z modelami Rails

  2. Na co zwrócić uwagę, jeśli Twoja replikacja PostgreSQL jest opóźniona

  3. Jak dostosować plik konfiguracyjny oficjalnego obrazu Docker PostgreSQL?

  4. Funkcja AVG() w PostgreSQL

  5. Jak mogę zatrzymać skrypt Postgres, gdy napotka błąd?